以下のようなSSLエラーが発生する。

Node.js

PS C:\workspaces\vscode\reactlesson> npm install react-create-app
npm ERR! Windows_NT 10.0.15063
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "reac
t-create-app"
npm ERR! node v6.10.2
npm ERR! npm  v3.10.10
npm ERR! code EPROTO
npm ERR! errno EPROTO
npm ERR! syscall write

npm ERR! write EPROTO 101057795:error:140943FC:SSL routines:ssl3_read_bytes:sslv3 alert bad record mac:openssl\ssl\s3_pkt.c:1493:SS
L alert number 20
npm ERR! 101057795:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:openssl\ssl\s3_pkt.c:659:
npm ERR!
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     

npm ERR! Please include the following file with any support request:
npm ERR!     C:\workspaces\vscode\reactlesson\npm-debug.log

SSLを使用しない用に、以下のファイルのregistry のプロトコルをhttps から http に編集する。

C:\Program Files\nodejs\node_modules\npm\lib\config\default.js

registry: 'http://registry.npmjs.org/',

Bower

インストールしたbowerでも同様のエラーが発生する

> bower search react


bower EPROTO        Request to https://bower.herokuapp.com/packages/search/react failed: write EPROTO 101057795:error:140943FC:SSL
routines:ssl3_read_bytes:sslv3 alert bad record mac:openssl\ssl\s3_pkt.c:1493:SSL alert number 20 101057795:error:1409E0E5:SSL rout
ines:ssl3_write_bytes:ssl handshake failure:openssl\ssl\s3_pkt.c:659:

Node.js と同様に、registry の プロトコルを https から http に変更する

\%USERPROFILE%\AppData\Roaming\npm\node_modules\bower\lib\node_modules\bower-config\lib\util\defaults.js

var defaults = {
    'directory': 'bower_components',
    'registry': 'http://bower.herokuapp.com',
    'shorthand-resolver': 'http://github.com/{{owner}}/{{package}}.git',
    'tmp': paths.tmp,
    'proxy': proxy,

CentOS7 へ Python3 をインストールして Django REST framework  アプリケーションのサンプルの動作確認ができたので、Gradleを使ってデプロイ手順の半自動化を試みる。

1.やりたいこと

とっかかりとして、最低限、以下程度のことをやりたい。

  1. GitからHEADリビジョンを取得
  2. Zip圧縮してアーカイブを作成
  3. SSH経由でサーバーへアーカイブをコピー
  4. アーカイブを展開

2.構成

ここまでで、Visual Studio Code上に作成した構造は以下のような感じ。あと、ワークスペース(django_api_lesson) 直下に以下を作成

  • デプロイ用アーカイブ作成用のディレクトリ(buid)を作成
  • Gradle用のビルドスクリプト(build.gradle)を作成
  • SSH KEY ファイル(id_rsa) を配置。

django_gradle01

SSH KEYファイルの作成

Gradle から SSHでログインするために、SSH KEYファイルを、ログイン先のサーバーで作成する。

[root@ganzin ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
28:90:51:e4:6d:a7:ae:8b:36:95:67:f2:83:b5:bf:fc root@ganzin
The key's randomart image is:
+--[ RSA 2048]----+
|  .oo            |
|   + .           |
|  o . o .        |
|   . . +         |
|    ..o S        |
|    +o+          |
|   . B..         |
|  o...+.         |
| ...o. o+oE      |
+-----------------+

ホームディレクトリの .ssh ディレクトリ配下に、id_rsa ファイルが生成されるので、FTPなどで、ローカルに取得する。

[root@ganzin .ssh]# ls 
id_rsa id_rsa.pub 

3.Gradle ビルドスクリプトの記述

Gradleインストール手順 に従いインストール。

上記、build.gradle に以下のようなスクリプトを記述。

buildscript{
    repositories {
        jcenter()
    }
    dependencies {
        // SSHプラグインの設定
        // https://gradle-ssh-plugin.github.io/
        classpath 'org.hidetake:gradle-ssh-plugin:2.9.0'
    }
}

plugins {
  // SSHプラグインの設定
  id 'org.hidetake.ssh' version '2.9.0'
}

// SSHプラグインの設定
apply plugin: 'org.hidetake.ssh'

// デフォルトで実行するタスク順に指定
defaultTasks 'clean', 'export', 'zip', 'deploy'

// 各種設定
final APP_NAME = 'firstapi' // アプリケーション名
final REOMOTE_PATH = '/home/piroto/djangoapp' // デプロイ先ディレクトリ
final BUID_DIR = 'build' // デプロイ用アーカイブ作成先ディレクトリ
final EXPORT_DIR = 'repo' // GITリポジトリExport先ディレクトリ

// SSH接続情報
// $ ssh-keygen -t rsa
// C:\Users\pppiroto\.ssh\known_hosts
remotes {
    web01 {
        host = '192.168.0.36'
        user = 'root'
        password = 'password'
        // SSH KEYファイルを指定(サーバーで、ssh-keygenで生成し、プロジェクトルートディレクトリに配置)
        identity = file('id_rsa')
    }
}

// デプロイ用アーカイブ作成先ディレクトリのクリーン
task clean {
    doLast {
        exec {
            executable 'cmd'
            args 'rmdir', '/S', '/Q', "${BUID_DIR}\\${EXPORT_DIR}"
        }
        exec {
            executable 'cmd'
            args 'del', "${BUID_DIR}\\${APP_NAME}.zip"
        }
    }
}

// ローカルGitリポジトリからHEADリビジョンをExport
// http://sakebook.hatenablog.com/entry/2014/09/03/084456
// http://qiita.com/scalper/items/1905b47209989dda5648
task export {
    doLast {
        exec {
            executable 'git'
            args 'checkout-index', '-a', '-f', "--prefix=${BUID_DIR}/${EXPORT_DIR}/"
        }
    }
}

// GitリポジトリからExportしたプログラムをZipに圧縮
task zip(type: Zip) {
    baseName = "${APP_NAME}"
    destinationDir = file("${BUID_DIR}")
    exclude "${APP_NAME}\\__pycache__"
    into("${APP_NAME}") {
        from ("${BUID_DIR}/${EXPORT_DIR}/${APP_NAME}") {
            include '**/*.*'
        }
    }
}

// SSHを利用してデプロイ用アーカイブを送信後、展開
task deploy {
    doLast {
        ssh.run {
            session(remotes.web01) {
                execute "rm -R -f ${REOMOTE_PATH}/${APP_NAME}"
                execute "rm -f ${REOMOTE_PATH}/${APP_NAME}.zip"
                put from:"${projectDir}\\${BUID_DIR}\\${APP_NAME}.zip", into:"${REOMOTE_PATH}/${APP_NAME}.zip"
                execute "unzip ${REOMOTE_PATH}/${APP_NAME}.zip -d ${REOMOTE_PATH}"
            }
        }
    }
}

Gradle ssh プラグインで reject HostKey エラー 発生時の対処

4.実行

PS C:\workspaces\vscode\django_api_lesson> gradle
:clean
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\workspaces\vscode\django_api_lesson>Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\workspaces\vscode\django_api_lesson>:export
:zip UP-TO-DATE
:deploy
web01#53|Archive:  /home/piroto/djangoapp/firstapi.zip
web01#53|   creating: /home/piroto/djangoapp/firstapi/
web01#53|  inflating: /home/piroto/djangoapp/firstapi/db.sqlite3
web01#53|   creating: /home/piroto/djangoapp/firstapi/firstapi/
web01#53|  inflating: /home/piroto/djangoapp/firstapi/firstapi/settings.py
web01#53|  inflating: /home/piroto/djangoapp/firstapi/firstapi/urls.py
web01#53|  inflating: /home/piroto/djangoapp/firstapi/firstapi/wsgi.py
web01#53|  inflating: /home/piroto/djangoapp/firstapi/firstapi/__init__.py
web01#53|  inflating: /home/piroto/djangoapp/firstapi/manage.py

BUILD SUCCESSFUL

Total time: 4.73 secs

OK OK

1.CentOS7 に Python3をインストール

1.1 IUS Community Project の yum リポジトリをインストール

Python 3 を CentOS 7 に yum でインストールする手順

IUS Community Project の yum リポジトリ
Python 3.x は CentOS 7 の標準 yum リポジトリでは提供されていませんので、別の yum リポジトリから取得する必要があります。
IUS Community Project は、Red Hat Enterprise Linux (RHEL) や CentOS 向けに、できる限り最新のソフトウェアの RPM を提供することを目的としたプロジェクトです。
PHP, MySQL, Python, Apache httpd, rsync, memcached, curl, openssl などのソフトウェアを RPM を提供しています。
この IUS Community Project のリポジトリを CentOS 7 に登録すれば、最新の Python を yum でインストールできるという訳です

# yum install -y https://centos7.iuscommunity.org/ius-release.rpm

1.2 Python3.6 をインストール

Python3.6 を検索して、インストール

# yum search python36
# yum install python36u

1.3 venv仮想環境を作成

ユーザーホームディレクトリ(/home/piroto/venv)にvenv仮想環境ディレクトリを作成

# cd /home/piroto/venv
# python3.6 -m venv django

Activate する

[root@ganzin bin]# pwd
/home/piroto/venv/django/bin
[root@ganzin bin]# . activate
(django) [root@ganzin bin]#

1.4 venv環境に必要なライブラリをインストール

開発環境に pip install したライブラリを確認し、

(django) PS C:\workspaces\venv\django\Scripts> pip freeze 
Django==1.11 
django-filter==1.0.2 
djangorestframework==3.6.2 
Markdown==2.6.8 
pytz==2017.2

上記で Activateした、CentOSのvenv環境にインストール

(django) [root@ganzin bin]# pip install Django==1.11
(django) [root@ganzin bin]# pip install django-filter==1.0.2
(django) [root@ganzin bin]# pip install djangorestframework==3.6.2
(django) [root@ganzin bin]# pip install Markdown==2.6.8

1.5 CentOSに以下必要なライブラリをインストール

Python3.6 を利用するので、mod_wsgi は、Pthon3.6用のものをインストールする

[root@ganzin bin]# yum install httpd-devel
[root@ganzin bin]# yum install python36u-mod_wsgi

2.デプロイ

2.1 モジュールデプロイ用にFTPサーバを設定する

2.2 サンプル用のDjango REST アプリケーションを圧縮し、デプロイ

サンプルアプリケーション

(1) settings.py の ALLOW_HOSTS に配置サーバーの IPアドレスを指定する(今回は*ですべて許容させる)よう指定

ALLOWED_HOSTS = ['*']

(2) django_api_lesson 直下の、firstapi を、zipで圧縮

django_centos7_03

(3) ホームディレクトリ配下に、djangoapp ディレクトリを作成し、そこに、firstapi.zipを配置(開発Windows端末側作業)

ftp> mkdir djangoapp
257 "/home/piroto/djangoapp" created
ftp> bin
200 Switching to Binary mode.
ftp> put "C:\workspaces\vscode\django_api_lesson\firstapi.zip"
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 11848 バイトが送信されました 0.02秒 592.40KB/秒。

(4) CentOS側にて解凍

[root@ganzin djangoapp]# unzip firstapi.zip

3.Apache 用 Django設定

3.1 /etc/httpd/conf.d/django.conf ファイルを作成し以下を記述

http://docs.djangoproject.jp/en/latest/howto/deployment/wsgi/modwsgi.html

項目 設定内容
WSGIScriptAlias デプロイしたアプリケーションのwsgi.pyを指定
WSGIPytonPath デプロイしたアプリケーションのルートディレクトリ、およびvenv仮想環境のライブラリディレクトリを指定。複数パスを指定する場合、: でつなぐ
Alias Django REST framework が使用する、css、JavaScriptなどの静的ファイルの参照先を指定
WSGIScriptAlias /firstapi /home/piroto/djangoapp/firstapi/firstapi/wsgi.py
WSGIPythonPath /home/piroto/djangoapp/firstapi:/home/piroto/venv/django/lib/python3.6/site-packages
<Directory /home/piroto/djangoapp/firstapi/firstapi>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

Alias /static/rest_framework /home/piroto/venv/django/lib/python3.6/site-packages/rest_framework/static/rest_framework/

<Directory /home/piroto/venv/django/lib/python3.6/site-packages/rest_framework/static/rest_framework>
Require all granted
</Directory>

3.2 /etc/httpd/conf.d/usedir.conf

ユーザーディレクトリにアプリケーションを配置する場合、UserDir を enable にする必要がある。

<IfModule mod_userdir.c>
    #
    # UserDir is disabled by default since it can confirm the presence
    # of a username on the system (depending on home directory
    # permissions).
    #
    UserDir enable

    #
    # To enable requests to /~user/ to serve the user's public_html
    # directory, remove the "UserDir disabled" line above, and uncomment
    # the following line instead:
    #
    #UserDir public_html
</IfModule>

これだけだと、実行時にPermissionエラーとなる。

[Tue May 02 21:49:38.552916 2017] [core:error] [pid 16163] (13)Permission denied: [client 192.168.0.29:56724] AH00035: access to /firstapi denied (filesystem path '/home/piroto/djangoapp') because search permissions are missing on a component of the path

home ディレクトリ以下に、実行権限 chmod +x が必要

# cd /home
# chmod 755 piroto

5.動作確認

http://192.168.0.36/firstapi

django_centos7_01

OK

http://192.168.0.36/firstapi/users/?format=json

django_centos7_02

OK

いくつかはまりながらも動作確認できた。めでたし。