Apache2などはASGIに対応しておらず、ASGIサーバーを内部に立てないといけない。
インターネット - Apache2 - ASGIサーバー という並びでやり取りする。
ASGIサーバーとしてchannelsが推奨しているのがdaphne(ダフネ)
DjangoのChannelは複数のインスタンス間で通信を必要とするため、Regisをインストールしておこう。
sudo apt-get install redis-server
また、最新版に変更するなら、Redisのアップグレードを参照。
dapfneの特徴
- LANのIPにはバインドできない。つまり、外部からの直接アクセスはできない様。
> daphne -b 0.0.0.0 -p 8001 yourproject.asgi:application
http://127.0.0.1:8001 (http://localhost:8001) にアクセスすると見える。
また、https用のASGIサーバーは、
> daphne -e ssl:8443:privateKey=yourkey.pem:certKey=yourcert.pem yourproject.asgi:application
で起動できる。
通常は、Apache2とDaphneは同じサーバー内で稼働するかと思われるので、その場合にはhttpで通信すればよい。
もしhttpsで通信したいのであれば、yourkey.pemとyourcert.pem を作成してSSLに対応できるようにしてください。
次に本番環境での話ですが、このままでは再起動などをしてくれないため、daphneをsupervisor上で動かすことにする。supervisorはデーモン(スレッド)監視プログラムなので、便利。supervisorのインストールは別途参照。
supervisorの設定だが、httpだと変巣numprocsの値を変更することにより、複数のインスタンスを作成することは簡単だったが、httpsだとあれこれやったが、1つのインスタンスしか動かすことができなかった。以下にsupervisorのconfを記載します。(私の場合、mail serverが、supervisor上で動いているので、ごちゃごちゃしていたらすいません。)
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
http用のconfファイル (unix socketを使い、複数のデーモンを立ち上げることができるそうだ。numprocs=1しか試してないが。)
[fcgi-program:daphne]
# TCP socket used by Nginx backend upstream
socket=tcp://localhost:8080
# Directory where your site's project files are located
directory=/home/gotodk1023/shopapp
user=gotodk1023
# Each process needs to have a separate socket file, so we use process_num
# Make sure to update "mysite.asgi" to match your project name
command=/home/gotodk1023/.virtualenvs/venv_shopapp/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access>
# Number of processes to startup, roughly the number of CPUs you have
numprocs=1
# Give each process a unique name so they can be told apart
process_name=daphne%(process_num)d
# Automatically start and recover processes
autostart=true
autorestart=true
environment=PLACE="PROD_A2_AS1"
このとき、がっつり気を付けないといけないのは、/run/daphne/ディレクトリを作成し、アクセス権を777などに変更。これをしないと動かなかった。また、run/に追加したディレクトリやファイルは再起動時に消えるので、cronにて、再起動時に追加・権限変更を加えてやる。
crontab -e
最後の行に以下を追加
@reboot mkdir /run/daphne && chmod 777 /run/daphne
次に、httpsでの通信用のconfファイル
[program:daphne_ssl]
# Directory where your site's project files are located
directory=/home/gotodk1023/shopapp
user=gotodk1023
# Each process needs to have a separate socket file, so we use process_num
# Make sure to update "mysite.asgi" to match your project name
command=/home/gotodk1023/.virtualenvs/venv_shopapp/bin/daphne -e ssl:8443:privateKey=/home/gotodk1023/local.key.pem:cer>
# Number of processes to startup, roughly the number of CPUs you have
numprocs=1
# Give each process a unique name so they can be told apart
process_name=daphne_ssl%(process_num)d
# Automatically start and recover processes
autostart=true
autorestart=true
environment=PLACE="PROD_A2_AS1"
[fcgi-program:daphne_ssl]では、動かなかったので、通常の[program:xxxxx]をしようした。この場合、複数のデーモンを立ち上げようとしたが、2つ目以降は常に起動と停止を繰り返したので、あきらめました。。。。すいません。
あと、テストでdaphneをsupervisorを使わずに動かしていると、Portが競合するのか、supervisorは立ち上がらないので、すべてのdaphneをKillしてからsupervisorを立ち上げるようにしてください。
service supervisor restart
service supervisor status
開発中に気を付けること(自分用)
- frontendなどをreactなどで作っているときは、まずwebpack-serverなどで開発。
- dephneサーバーを使用するときは、djangoのcollectstaticを忘れずにすること。dephneはpython manage.py runseverとは違い、アプリケーション内のフォルダを見に行ったりはしない。
apache側の設定
まず、以下のモッドをアクティブにする必要がある。
proxy.load
proxy_http.load
proxy_wstunnel.load
(いらないのもあるかも。)
/etc/apache2/mods-available内に移動し、A2enmod modefilename.loadを実行する。
a2enmod rewrite
a2enmod proxy.load
a2enmod proxy_http.load
a2enmod proxy_wstunnel.load
次に、apache2のコンフィグファイルを変更する。virtualhost内を以下に変更する。
Port番号はご自分でお好きなのを選んでください。
MDomain shopapp.take-my-order.com
MDCertificateAgreement accepted
<VirtualHost *:443>
SSLEngine on
ServerName shopapp.take-my-order.com
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} Upgrade [NC]
# RewriteRule /(.*) wss://localhost:8443/$1 [P,L] <= SSLなこちら
RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
# SSLProxyEngine on <= SSLなこちら
# ProxyPass / https://localhost:8443/ <= SSLなこちら
# ProxyPassReverse / https://localhost:8443/ <= SSLなこちら
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
<VirtualHost *:80>
ServerName shopapp.take-my-order.com
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
これで、このサブドメインのアドレスは、リバースプロキシサーバーのようなに、内部のポート番号8080のサーバーにアクセスするようになる。
ちなみに、SSL化をしなくても、apacheまではSSL、内部は非SSLで通信できているようだ。