Nginx + Gunicorn + Supervisorの組み合わせでDjangoアプリケーションを立ち上げたので手順のメモ
今回はOSに何も入っていない状態から始めていきます
環境
OS: Amazon Linux AMI
Python: 3.6.1
Django: 1.11.4
Nginx: 1.10.3
Gunicorn: 19.7.1
Supervisor: 3.3.3
Nginxのインストール
nginxのインストール
$ sudo yum install nginx
nginx起動する
$ sudo nginx
nginx自動起動設定
$ sudo chkconfig --add nginx
$ sudo chkconfig nginx on
自動起動設定確認
以下のようになっていればok
$ chkconfig | grep nginx
nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off
http://ipアドレス
にアクセスしちゃんと起動しているか確認する
以下の通りになっていればOK
Python環境の構築
今回はAnacondaで構築した
こちらからPython 3.6 versionをダウンロードする
ダウンロードしたパッケージをCyberduckなどのFTPツールで/home/ec2-userにアップロードする
アップロード完了したら下記コマンドでAnacondaインストールする
$ bash Anaconda3-4.4.0-Linux-x86_64.sh
インストール完了後、Anacondaのコマンドが使えるようにPATHを通す
$ export PATH="$PATH:/home/ec2-user/anaconda3/bin"
condaのコマンドを打って確認
$ conda info -e
# conda environments:
#
root * /home/ec2-user/anaconda3
良さげです
なお、annacondaインストール時にbashrcに環境変数の設定を追加していると
Do you wish the installer to prepend the Anaconda3 install location
to PATH in your /root/.bashrc ? [yes|no]
[no] >>> yes
ルート環境のpythonも3.6になっている
$ python --version
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
Djangoプロジェクトの作成
今回は直接EC2上でプロジェクトを作成します
本来はローカルで開発したDjangoアプリケーションをgit cloneすべき
また、DBもデフォルトのSQliteを使用しますが、実際のサービスを公開するにはPostgresqlやMariaDBを使う
まずはDjangoのインストール
root環境で動かすかどうかは少し議論の分かれるところで、別に環境を作ってDjangoを動かした方がいいんじゃないか、と思ったりもしますが、とりあえず今回はroot環境でインストールしてしまいます
$ pip install django
問題なければプロジェクトを作成
$ django-admin startproject test_project
プロジェクトが作られていることを確認
$ ls -ltr
total 511032
-rw-rw-r-- 1 ec2-user ec2-user 523283080 Aug 3 04:50 Anaconda3-4.4.0-Linux-x86_64.sh
drwxrwxr-x 20 ec2-user ec2-user 4096 Aug 3 04:53 anaconda3
drwxrwxr-x 3 ec2-user ec2-user 4096 Aug 3 05:05 test_project
/test_project/test_project/settings.py
のALLOW HOSTを下記の通り編集しておく
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["サーバのIPアドレス"]
下記のコマンドでDjangoを起動
デフォルトだと127.0.0.1:8000がbindアドレスとして使用されているため、オプションで0.0.0.0:8000
を追加する必要があります
また、事前にAWSのセキュリティグループで8000番ポートを解放しておく必要があります
$ cd test_project
$ python manage.py runserver 0.0.0.0:8000
そして、http://IPアドレス:8000
にアクセスすると以下の通りDjangoアプリケーションにアクセスできる
Gunicornのインストール
GunicornはPython製のWSGIサーバ
WSGIサーバというのはWebサーバとWebアプリケーションをつなぐサーバのこと
なので、Nginx <-> Gunicorn <-> Django
というような構成をイメージしていただければと
まずはGunicornのインストールをやっていく
$ pip install gunicorn
インストールされたらGunicornでDjangoを起動させる
$ gunicorn test_project.wsgi --bind=0.0.0.0:8000
先程と同様、http://IPアドレス:8000
にアクセスするとDjangoアプリケーションに接続できる
なお、settings.pyを本番用とか開発用で分けている場合は以下のような感じで
$ gunicorn test_project.wsgi.wsgi --env DJANGO_SETTINGS_MODULE=test_project.settings_dev --bind=0.0.0.0:8000
Nginxの設定の変更
/etc/nginx.confを以下の通り編集する
〜中略〜
http {
〜中略〜
upstream app_server {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
#以下4行はコメントアウト
#listen 80 default_server;
#listen [::]:80 default_server;
#server_name localhost;
#root /usr/share/nginx/html;
# 以下3行を追加
listen 80;
server_name IPアドレス or ドメイン;
client_max_body_size 4G;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
# 以下4行を追加
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
〜以下略〜
編集したら下記コマンドでnginxを再起動する
$ sudo service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]
これでNginxでのリバースプロキシの設定は完了
今回はnginx.confを直接編集したけれど、設定ファイルをどこか別のところに書いてそれを読み込ませる、という方法でもOK
その後、DjangoをGunicornで立ち上げる
$ gunicorn test_project.wsgi --bind=0.0.0.0:8000
次はhttp://IPアドレス
にアクセスするとDjangoの画面が表示されるはず
Supervisorでプロセスをデーモン化する
今の状態だとGunicornのコマンドを中止したり、サーバからログアウトするとアプリケーションが停止してしまう
これを解消するためにSupervisorでGunicornのプロセスをデーモン化する
早速、Supervisorをインストール、としたいところだけれど、SupervisorはPython2系でしか動作しない
そのためAnacondaでPython2系の仮想環境を構築し、その環境にSupervisorをインストールしていく
まずは下記コマンドでSupervisor用のPython2系の仮想環境を作る
$ conda create -n supervisor python=2.7
python2系の環境に切り替えてpipでsupervisorをインストール
$ source activate supervisor
$ pip install supervisor
問題なくインストールできたら、supervisorの設定ファイルを作成し、それを/etc配下に配置する
$ echo_supervisord_conf > supervisord.conf
$ sudo mv supervisord.conf /etc
次にsupervisorの設定を行うため、supervisord.confを下記の通り編集
〜中略〜
[supervisord]
logfile=/var/log/supervisord.log ; ログの場所を変更
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log #コメントアウト
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/var/run/supervisord.pid ; 追記
;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid #コメントアウト
〜中略〜
# includeはコメントアウトされているのでコメント外す
[include]
files = supervisord.d/*.conf ; 起動するプロセスのconfファイルの配置場所
;files = relative/directory/*.ini
ログファイルは作っておき、パーミッションも設定しておく
$ sudo touch /var/log/supervisord.log
$ sudo chown ec2-user /var/log/supervisord.log
$ sudo chgrp ec2-user /var/log/supervisord.log
$ sudo chmod 774 /var/log/supervisord.log
あと、ログローテションも設定しておく
$ sudo sh -c "echo '/var/log/supervisord.log {
missingok
weekly
notifempty
nocompress
}' > /etc/logrotate.d/supervisor"
次にデーモン化するプロセスのコマンドを記載したファイルを作っていく
まずはそれらのファイルを配置するディレクトリを作成
$ sudo mkdir /etc/supervisord.d
/etc/supervisord.d配下にdjango_app.confを作成
ここに、Gunicornのプロセスをデーモン化するための設定を以下のように書く
[program:django_app]
directory=/home/ec2-user/test_project
command=gunicorn test_project.wsgi --bind=0.0.0.0:8000
numprocs=1
autostart=true
autorestart=true
user=ec2-user
redirect_stderr=true
directoryに実行するディレクトリを指定、commandのところにプロセスを起動するためのコマンドを指定する
ここまでできたら下記のコマンドでsupervisorを立ち上げる
$ supervisord
次に、confファイルを読み込ませる
こちらは仮にconfを修正などする場合は必ず実行する
$ supervisorctl reread
なお、下記のコマンドでデーモンを再起動し、そのタイミングでもconfが読み込まれたりする
$ supervisorctl reload
下記のコマンドでGunicornのプロセスをデーモン化する
$ supervisorctl start django_app
仮にdjango_app: ERROR (already started)
というメッセージが出た場合は、以下のコマンドでプロセスの再起動をしたり、停止をしてからstartしたりする
$ supervisorctl stop django_app # 停止
$ supervisorctl restart django_app # 再起動
さて、この状態でサーバからログアウトしてみる
そして、http://IPアドレス
にアクセスすると、Djangoの画面が表示される
GunicornのプロセスがSupervisorによりデーモン化されていることになる
よかったですね