前回EC2のインスタンス作成からgitを通したアプリフォルダのデプロイまで行いました。
今回はその続きからで、Gunicorn、Nginxの設定をして自動的にアプリとサーバーが起動するようにしていきたいと思います。
ざっくりイメージにするとこのような構成になります。
WebサーバであるNginxとDjangoアプリケーションの間にGunicornというWSGIインターフェースをかますことによって、より安定性と処理スピードが上がります。
Djangoディレクトリ構成
今回例に挙げるDjangoアプリのディレクトリ構成は以下のとおりです。ml-django-appというアプリ名がそのままトップのディレクトリ名になっており、configという設定フォルダ(通常はトップのディレクトリ名と同じことが多い)やmachineというアプリケーションフォルダがあります。
※内容は一部省略しているため、実際には以下に含まれていないファイルやフォルダもあります。
ml-django-app
├── config
│ ├── settings.py
│ └── wsgi.py
├── machine
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── requirements.txt
├── static
└── templates
Gunicorn側の設定
Nginxを呼び出すためのアプリケーションサーバーGunicornの設定をしていきます。
Gunicorn動作確認
ssh接続でubuntu内に入り、仮想環境をアクティベートしてデプロイしたアプリディレクトリに移動します。
[ubuntu内]$ source myenv/bin/activate
[(myenv) ubuntu内]$ cd ml-django-app
Gunicornが入っているか確認します。
[(myenv) ubuntu内:~/ml-django-app]$ which gunicorn
/home/ubuntu/myenv/bin/gunicorn
Gunicornの存在を確認したら、Gunicornを起動してみます。
[(myenv) ubuntu内:~/ml-django-app]$ gunicorn --bind 0.0.0.0:8000 config.wsgi
config.wsgiのconfig部分にはwsgi.pyが格納されているディレクトリ名を記載します。こちらの名称については適宜変更してください。また、wsgi部分は単純にwsgi.pyのpyを省いた形で記載します。
この状態で「xxx.xxx.xxx.xxx:8000」にアクセスをしてみて、アプリの動作が正常かどうか確認します。
確認をしたら、Control + CでGunicornを終了し、さらに
[(myenv) ubuntu内:~/ml-django-app]$ deactivare
で仮想環境を終了します。
起動自動化設定
OS起動時に自動的にGunicornが立ち上がる設定をしていきます。
djangoアプリトップ階層にいるか確認します。
[ubuntu内:~/ml-django-app]$ pwd
/home/ubuntu/ml-django-app
Gunicornのパラメータ設定用にgunicorn.serviceというファイルを作成します。
sudo vi /etc/systemd/system/gunicorn.service
以下の設定を書き込みます。
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/ml-django-app
ExecStart=/home/ubuntu/myenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/ubuntu/ml-django-app/ml-django-app.sock config.wsgi:application
[Install]
WantedBy=multi-user.target
workers 3〜の箇所は「/home/ubuntu/アプリ名(トップ階層ディレクトリ名)/アプリ名.sock wsgi.pyが格納されているディレクトリ名.wsgi:application」 となりますのでご注意ください。
:wqで保存したら以下をコマンドします。
[ubuntu内:~/ml-django-app]$ sudo systemctl start gunicorn
[ubuntu内:~/ml-django-app]$ sudo systemctl enable gunicorn
うまくいくとシンボリックリンクが貼られます。
また、
[ubuntu内:~/ml-django-app]$ ls /home/ubuntu/ml-django-app
で先ほど設定したソケットファイル「ml-django-app.sock」があるか確認します。
続いてGunicornのプロセスの詳細について確認します。
[ubuntu内:~/ml-django-app]$ sudo systemctl status gunicorn
もしうまくGunicornが起動できない場合は
[ubuntu内:~/ml-django-app]$ sudo journalctl -u gunicorn
で詳細のログからエラーメッセージなどを確認します。
gunicornの終了はqをコマンドします。
Nginx側の設定
前章ではクライアントからDjangoアプリを直接呼び出す状態から、Gunicornを呼び出すという設定にしました。GunicornはPythonを実行するソフトウェアで負荷が大きいため、Pythonは必要な時だけ実行したいところです。そこで、HTMLなど静的なページはより軽量なNginxというWebサーバーを使用し、Pythonが必要になった時だけNginxからGunicornを経由してDjangoアプリを実行するという3段階の構造にします。
以降はNginx側の設定をしていきます。
sites-availableがあるか確認するために以下のディレクトリに移動します。
[ubuntu内:~/ml-django-app]$ cd /etc/nginx
lsで確認したら、sites-availableに移動します。
[ubuntu内:~/etc/nginx]$ cd sites-available
今回のDjangoアプリ用の設定をするため、ファイルを作成します。
[ubuntu内:~/etc/nginx/sites-available]$ sudo vi ml-django-app
以下の設定内容を書き込みます。
server {
listen 80;
server_name 54.178.251.205;
location = /favicon.ico {access_log off; log_not_found off;}
location /static/ {
root /home/ubuntu/ml-django-app;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/ml-django-app/ml-django-app.sock;
}
}
server_nameはElasticIPを指定し、他ディレクトリ名などは適宜変更してください。
:wqで保存し、シンボリックリンクを貼ります。
[ubuntu内:~/etc/nginx/sites-available]$ sudo ln -s /etc/nginx/sites-available/ml-django-app /etc/nginx/sites-enabled/
念のためリンクを貼ったところを確認します。
[ubuntu内:~/etc/nginx/sites-available]$ ls -la /etc/nginx/sites-enabled/
次に作成したファイルの内容があっているか確認します。
[ubuntu内:~/etc/nginx/sites-available]$ sudo nginx -t
Nginxを再起動します。
[ubuntu内:~/etc/nginx/sites-available]$ sudo systemctl restart nginx
ubuntuファイアウォールの8000番ポートを無効化します。
[ubuntu内:~/etc/nginx/sites-available]$ sudo ufw delete allow 8000
Nginxのアクセスを許可します。
[ubuntu内:~/etc/nginx/sites-available]$ sudo ufw allow ’Nginx Full’
HTTP80番ポートからの通信を許可するため、EC2のセキュリティグループにインバウンドルールを追加します。
Djangoアプリトップ階層に移動し、以下をコマンドします。
[ubuntu内:~/ml-django-app]$ sudo systemctl restart gunicorn
IPでアクセスをしてみて、アプリが自動的に立ち上がるか確認します。
次回は独自ドメイン設定とSSL化をし「https://○○○.com」のような形でアクセスができるように設定していきたいと思います。
コメント