- Gunicornの設定が難しすぎる…
- 動かすコマンドは?
- 実践的な設定方法を教えて!
このような方に向けて書きました。
中小規模のDjangoアプリのデプロイによく使われるアプリケーションサーバーがGunicornです。
ところが、初めての設定・起動は少し戸惑うことも多いはず。
本記事では以下のような内容を解説します。
- ワーカー数の設定
- Nginxとの連携
- UNIXソケットとTCPの使い分け
- Systemdを使った自動化の手順
本記事を読み終わる頃には、Gunicornの苦手意識がだいぶ薄らいでいるはずです。
ぜひ、手を動かしながら身につけていきましょう。
Gunicornの基本的な動かし方
まずはGunicornを動かすための基本から押さえていきましょう。
実践でよく使われるSystemdへの登録でも必要な知識になりますので、ぜひ理解していきましょう。
Gunicornのインストール
一般的なPythonパッケージと同様、pipやpoetryでインストールができます。
# pipの場合
pip install gunicorn
# poetryの場合
poetry add gunicornできればローカルでの開発中にインストールを済ませておきましょう。
Gunicornを立ち上げる(簡易版)
簡単にGunicornを立ち上げたい場合には、次のコマンドを実行します。
gunicorn --workers 7 プロジェクト名.wsgi:applicationこのコマンドは開発環境や簡単なテストで使われるものです。
本番環境ではSystemdを使って自動制御する方法がよく使われるので、記事の後半で解説します。
ここでgunicornコマンドに渡している2つの引数を解説します。
Gunicornワーカー
--workers 7とすることで、7つのプロセスを起動しています。
Gunicornの公式ドキュメント によると、ワーカー数の計算方法は以下の通りです。
(CPUコア数 × 2) + 1
たとえば契約したサーバーのCPUコア数が3なら、ワーカー数は7となります。
ちなみにLinuxの場合には、次のコマンドでCPUコア数を調べられます。
nprocとはいえこの数値は目安に過ぎないので、実際の稼働状況を見ながら調整する必要はあります。
WSGIアプリケーション
プロジェクト名.wsgi:applicationには、Gunicornが起動したら最初に読み込むエントリーポイントを指定します。
たとえば以下のようなDjangoプロジェクトなら、core.wsgi:applicationです。
.
├── core
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
├── poetry.lock
└── pyproject.tomlデプロイ時のDjangoアプリのエントリーポインはwsgi.pyなので、このような設定になるわけです。
より実践的なGunicornの使い方
gunicornコマンドを実行した場合、次のケースではGunicornを手動で再起動する必要があります。
- サーバーを再起動した場合
- Gunicornプロセスが停止した場合
サーバーは起動し続ける必要があるため、手動での再起動は現実的ではないです。
本番環境では、サービスを安定稼働させるために、SystemdでGunicornを自動管理(再起動・停止・監視)させます。
GunicornをSystemdサービスに設定
Gunicornサービスファイルを作成します。
sudo vi /etc/systemd/system/gunicorn.serviceviエディタが開くので、以下の内容を追記してください。
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/your/project
ExecStart=仮想環境へのパス/bin/gunicorn --workers 7 --bind 127.0.0.1:8000 プロジェクト名.wsgi:application
[Install]
WantedBy=multi-user.targetここで書き換えるべきは、ハイライトした箇所です。
WorkingDirectory
WorkingDirectoryには、Djangoプロジェクトまでのパスを指定します。
パスの調べ方は、manage.pyがあるディレクトリまで降りてからpwdコマンドを実行してください。
cd /path/to/your_project_root
pwdここで返ってきたパスをWorkingDirectoryに指定してあげればOKです。
ExecStart
ExecStartはGunicornを立ち上げるコマンドを書く場所です。
まずExecStart=の後に書くパスは「Gunicornの実行ファイルがあるパス」を指定し、次のコマンドで知ることができます。
which gunicorn--workerの後の数字は、すでに説明したとおりサーバーのCPUコア数から求められます。
(CPUコア数 × 2) + 1
プロジェクト名.wsgi:applicationの部分もすでにご紹介したとおりですね。
Gunicornが最初に読み込むエントリーポイントを指定することになります。
--bindについては、UNIXソケットを使う方法とTCPを使う方法があるので、後ほど詳しく解説します。
サービスをリロードして有効化
Gunicornサービスを有効化するため、サービスをリロードします。
# サービスファイルの変更をsystemdに認識させる
sudo systemctl daemon-reload
# Gunicornサービスを起動
sudo systemctl start gunicorn
# サーバー再起動時にGunicornサービスが自動的に起動するよう設定
sudo systemctl enable gunicornこれでGunicornが自動管理されるようになりました。
UNIXソケットを使う方法とTCPを使う方法
Systemdサービスの設定ファイルに--bindを指定しました。
ここではこの項目に設定するUNIXソケットとTCPに関する設定方法をお伝えします。
TCPとUNIXソケットの使い分け
端的に、次の基準で使い分けると良いです。
- TCP
- NginxとGunicornが別サーバーにある
- または別コンテナにある
- UNIXソケット
- NginxとGunicornが同じサーバーにある
基本的にはUNIXソケットの方がパフォーマンスやセキュリティ面で有利なので、優先して使うべきです。
どうしてもUNIXソケットが使えない場合には、TCPを選択するイメージで良いかと思います。
UNIXソケットの設定方法
UNIXソケットは、ファイルで通信する方法です。
--bindにはUNIXソケットファイルパスを指定します。
gunicorn --workers 7 --bind http://unix:/run/sock/my_project.sock プロジェクト名.wsgi:application/run/my_project.sock はソケットファイルの絶対パスです。
NginxとGunicornは、このファイルを中継してやりとりをします。
Nginxの設定ファイルでは、proxy_passにUNIXソケットを指定します。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://unix:/run/sock/my_project.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}上記の設定では/run/sockディレクトリ内のソケットファイルをwww-dataユーザーが読み込み・編集を行います。
そのため、/run/sockディレクトリを作成してwww-dataに権限を付与しておきましょう。
sudo mkdir /run/sock/
sudo chown www-data:www-data /run/sock/
sudo chmod 750 /run/sock/この設定では、80番ポートに飛んできたリクエストをUNIXソケット経由でGunicornに転送しています。
TCPバインドの設定方法
Gunicorn がリクエストをHTTPで受け取る場合にTCPバインドを使います。
- Nginx と Gunicorn が別のサーバーにある
- GunicornをHTTPサーバーとして公開する
こんな時にはUNIXソケットが使えないので、消去法的にTCPバインドを使うことになります。
gunicorn --workers 7 --bind 0.0.0.0:8000 プロジェクト名.wsgi:application上記の例では、IPアドレスとして0.0.0.0を指定しました。これは、すべてのインターフェースでリクエストを受け付けるという意味です。
また8000は、Gunicornで標準的なポート番号です。
Ningxの設定ファイル例は以下のとおりです。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}proxy_pass で Gunicorn がバインドされたアドレスとポートに転送します。
この設定では、クライアントからのリクエストをNginxが受け取り、127.0.0.1:8000 で待ち受けているGunicornに転送します。
まとめ
本記事では、Gunicornの基本から実践的なSystemdへの登録方法まで解説しました。
最初は戸惑うかもしれませんが、ワーカー数の設定やNginxとの連携、Systemdを使った自動化の設定など、一度理解してしまえばそこまで複雑なツールではありません。
Gunicornを正しく設定できると、Djangoアプリケーションを安定して本番稼働できるようになるのでマスターしていきましょう。
特にUNIXソケットは、パフォーマンス・セキュリティを両立できるので必須項目です。
ぜひ、手を動かしてGunicornを身につけていってください。

コメント