DjangoをVPSにデプロイする6〜Gunicorn編〜

DjangoをVPSにデプロイする5〜Djangoの設定編〜の続きです。

この記事ではVPSにGunicornの設定をしていきます。

開発環境ではrunserverで動いてたものを、VPSではNginxと連携してGunicornでrunserverの状態にします。

前知識

  • プロジェクト名.socket(独自のファイルを作成)
    「.sock」ファイルの元になります。
  • プロジェクト名.service(独自のファイルを作成)
    自動でGunicornを起動するWSGI仕様のコマンドを登録します。
  • gunicorn.sock(自動生成)
    マーカーのような物になります。

Nginxがsockファイルを目印にして、serviceファイルを実行しrunserverするというイメージです。


socketファイル作成

「/etc/systemd/system/」ディレクトリに作成します。

$ sudo vi /etc/systemd/system/プロジェクト名.socket

内容を以下のように設定します。

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/home/ユーザー名/プロジェクト名/プロジェクト名/プロジェクト名.sock

[Install]
WantedBy=sockets.target

Description

socketファイルの説明です。

ListenStream

「.sock」を作成する場所と名前です。manage.pyのディレクトリを指定しています。

WantedBy

「sockets.target」を指定。これはお決まりらしい。


serviceファイル作成

プロジェクト更新時、Gunicornを毎回起動するのは手間なのでコマンドを登録します。

$ sudo vi /etc/systemd/system/プロジェクト名.service

内容を以下のように設定します。

[Unit]
Description=gunicorn daemon
Requires=プロジェクト名.socket
After=network.target

[Service]
WorkingDirectory=/home/ユーザー名/プロジェクト名/プロジェクト名

ExecStart=/home/ユーザー名/プロジェクト名/仮想環境名/bin/gunicorn \
    --workers 3 \
    --bind /home/ユーザー名/プロジェクト名/プロジェクト名/プロジェクト名.sock \
    プロジェクト名.wsgi:application

[Install]
WantedBy=multi-user.target

Description

serviceファイルの説明です。

Requires

serviceファイルを起動した時に、socketファイルの起動要求を行います。

After

「network.target」を指定します。これはお決まりらしい。

WorkingDirectory

runserverするディレクトリを指定します。manage.pyのあるディレクトリになります。

ExecStart

実行するコマンドを登録します。(見やすくするためバックスラッシュで改行しています)

gunicornまでのパスを指定し、オプションで.sockファイルを指定します。

「–workers 3」はプロセス数なので好きな値にしてください。デフォルト値は1なので変更しておきましょう。

ExecStart=/home/ユーザー名/プロジェクト名/仮想環境名/bin/gunicorn \
    --workers 3 \
    --bind /home/ユーザー名/プロジェクト名/プロジェクト名/プロジェクト名.sock \
    プロジェクト名.wsgi:application

通常は?

serviceファイル作成を作成しましたが、これを登録しない場合次のコマンドで起動します。

$ cd プロジェクト名
$ sudo gunicorn プロジェクト名.wsgi:application

詳しくはGunicorn公式ドキュメントを見ると勉強になるかもです。


再読み込み

systemdマネージャーの設定を再読み込みさせます。

$ sudo systemctl daemon-reload

現状の確認

Nginxのステータスを確認

$ sudo systemctl status nginx

Gunicornのステータスを確認

$ sudo systemctl status プロジェクト名.service

activeになっていれば起動できています。


コマンド一覧

Nginx

テスト
$ sudo nginx -t

Nginxの起動
$ sudo systemctl start nginx

Nginxの再起動
$ sudo systemctl restart nginx

Nginxの停止
$ sudo systemctl stop nginx

Nginxのステータス
$ sudo systemctl status nginx

Gunicorn

2つ書いてありますがどちらでもいけます。

再読み込み
$ sudo systemctl daemon-reload

Gunicornの起動
$ sudo systemctl start プロジェクト名.service
$ sudo systemctl start プロジェクト名.socket

Gunicornの再起動
$ sudo systemctl restart プロジェクト名.service
$ sudo systemctl restart プロジェクト名.socket

Gunicornの停止
$ sudo systemctl stop プロジェクト名.service
$ sudo systemctl stop プロジェクト名.socket

Gunicornのステータス
$ sudo systemctl status プロジェクト名.service
$ sudo systemctl status プロジェクト名socket

サイトへ!

80番ポートを設定したので、「http://ドメイン」にアクセスするとページが開けるはずです。

もし開けなければエラーの内容をみて修正して下さい。

エラーログファイル

$ sudo less /var/log/nginx/error.log

エラーログで「bind() to 0.0.0.0:80 failed (98: Unknown error):のようなものがでたら、プロセスをキルすればこのエラーは解消されます。

80番ポートのプロセス確認

$ sudo lsof -i:80

nginx   37443      root    6u  IPv4 173793      0t0  TCP *:http (LISTEN)
nginx   37443      root    7u  IPv6 173794      0t0  TCP *:http (LISTEN)
nginx   37749  username    6u  IPv4 173793      0t0  TCP *:http (LISTEN)
nginx   37749  username    7u  IPv6 173794      0t0  TCP *:http (LISTEN)
nginx   37750  username    6u  IPv4 173793      0t0  TCP *:http (LISTEN)
nginx   37750  username    7u  IPv6 173794      0t0  TCP *:http (LISTEN)
nginx   37751  username    6u  IPv4 173793      0t0  TCP *:http (LISTEN)
nginx   37751  username    7u  IPv6 173794      0t0  TCP *:http (LISTEN)

左から2番目の数字がプロセスのIdなのでこれらをキル。

$ sudo kill 37443 37749 37750 37751

Nginxの再起動

$ sudo systemctl restart nginx

これでGunicorn編は終了です!

次は「DjangoをVPSにデプロイする7〜SSL・IP拒否・http/2編〜」です。