Gunicorn実践ガイド:WSGIサーバーで実現するPythonアプリの安定デプロイと運用最適化
Gunicorn とは
Gunicorn(“Green Unicorn”の略)は、Python アプリケーション向けの軽量で安定した WSGI HTTP サーバーです。Django、Flask などの WSGI 準拠フレームワークと組み合わせて使われることが多く、プロダクション環境でのデプロイに広く採用されています。シンプルな設計と豊富な設定オプション、複数のワーカーモデル(同期・スレッド・非同期)への対応が特徴です。
基本的な位置付け(WSGI と Gunicorn)
WSGI(Web Server Gateway Interface)は、Python のウェブアプリケーションとウェブサーバーを結ぶ標準仕様です。Gunicorn はこの WSGI を実装するアプリケーションサーバーで、アプリの「application」オブジェクト(例:Django の wsgi.application)を受け取り HTTP リクエストを処理します。通常はリバースプロキシ(例:NGINX)と組み合わせ、静的ファイルや TLS 終端はプロキシ側で行う運用が一般的です。
アーキテクチャの概要
- マスタープロセス:Gunicorn を起動するとまずマスター(親)プロセスが動作し、設定の読み込み、ログ設定、ワーカーの生成・管理を行います。
- ワーカープロセス:実際にリクエストを処理する子プロセス群。ワーカーモデル(後述)により、同期処理・スレッド・イベント駆動など異なる並列処理方式を選択できます。ワーカーがクラッシュしてもマスターが再起動することで耐障害性を確保します。
- プレフォークモデル:UNIX の伝統的なプリフォーク方式(親プロセスが子を fork して生成)を採用。Ruby の Unicorn に影響を受けた設計です。
ワーカーの種類(代表例)
Gunicorn には複数のワーカークラスがあり、用途やアプリの性質に応じて選びます。
- sync(デフォルト):各ワーカーが1リクエストずつ同期的に処理。CPUバウンドではなく I/O バウンドが少ない場合にシンプルで安定。
- gthread:1ワーカー内で複数スレッドを利用。軽量に同時接続数を増やしたい場合に有効。
- gevent / eventlet:協調的な非同期(コルーチン)ベース。多数の同時接続や長時間接続を扱うときに適切。ただし、外部ライブラリの互換性や monkey patching に注意。
- meinheld などのサードパーティ:Cベースの高速なワーカー(別パッケージ必要)。高性能を求める場合に検討。
- ASGI 連携:Gunicorn 自体は WSGI 用だが、uvicorn のワーカー(uvicorn.workers.UvicornWorker)を使うことで ASGI アプリを動かす方法がある。ただし本格的な ASGI 運用では Uvicorn/Hypercorn を直接使う方が自然な場合もある。
インストールと基本的な起動例
インストールは pip で簡単です(仮想環境推奨)。
pip install gunicorn
アプリケーションを起動する基本例:
gunicorn myproject.wsgi:application -w 4 -b 127.0.0.1:8000
- -w / --workers:ワーカー数
- -b / --bind:バインドするアドレス
- --access-logfile / --error-logfile:ログ出力先
設定ファイル(Python)例
多くの設定はコマンドラインの代わりに Python の設定ファイルで管理できます(例:gunicorn.conf.py)。
bind = '127.0.0.1:8000' workers = 3 worker_class = 'gthread' threads = 4 timeout = 30 accesslog = '-' errorlog = '-'
NGINX と組み合わせた典型的な構成
Gunicorn は一般に直接インターネットに公開せず、NGINX をリバースプロキシとして前段に置きます。NGINX は静的ファイル、TLS 終端、負荷分散、接続のスロットリングを担当し、Gunicorn はアプリケーションロジックに集中します。簡単な NGINX の location 設定:
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;
}
プロダクションでの運用(systemd 例)
systemd 管理下で Gunicorn を動かすとプロセス管理・自動再起動が容易です。簡単な unit ファイル例:
[Unit] Description=gunicorn daemon After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/path/to/project ExecStart=/path/to/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 myproject.wsgi:application Restart=on-failure [Install] WantedBy=multi-user.target
チューニングとベストプラクティス
- ワーカー数の目安:一般的には (2 x CPUコア) + 1 の式がよく使われますが、アプリの特性(CPU バウンド vs I/O バウンド)で調整すること。
- タイムアウト(timeout):長時間ブロッキングする処理がある場合は適切に設定。短すぎると正当なリクエストが切断される。
- max-requests:ワーカーのメモリリーク対策として一定リクエストごとにワーカーを再起動する設定(例:max-requests と max-requests-jitter)。
- keepalive:バックエンドでのコネクション再利用によりパフォーマンス向上。
- ログ:access / error ログを適切に収集(ログ回転や外部ログ集約サービスの利用を検討)。
- 非同期ワーカーを選ぶ場合:外部ライブラリの互換性・monkey patching の影響を確認すること。
信号(シグナル)による制御とロールアウト(概説)
Gunicorn は UNIX シグナルでランタイム制御が可能です。これにより、ワーカーの再生成、ログファイルの再オープン、ワーカー数の増減、グレースフルな再起動などを行えます。ゼロダウンタイムデプロイやローリングアップグレードの仕組みを組み合わせることで運用の柔軟性が増します(詳細は公式ドキュメント参照)。
注意点・制限
- Gunicorn 自体は WSGI サーバー:ASGI(WebSocket や HTTP/2 等)をネイティブに扱うには別の選択肢(Uvicorn, Daphne, Hypercorn など)を検討。
- 長時間のブロッキング処理はワーカーを枯渇させるため避ける(バックグラウンド処理は Celery 等を使用)。
- 非同期ワーカーは便利だが、利用するライブラリや拡張との相性を十分に確認する必要あり。
セキュリティに関するポイント
- TLS 終端は通常 NGINX などのフロントに任せ、Gunicorn は内部ネットワークで動作させる。
- Gunicorn 自身は特権(root)での実行を避け、専用の非特権ユーザーで動かす。
- 公開用に直接置く場合は、アップデートや脆弱性情報のチェックを怠らない。
まとめ
Gunicorn はシンプルかつ実績のある WSGI サーバーで、設定の自由度と信頼性から多くの Python Web アプリケーションで採用されています。アーキテクチャ(マスター/ワーカー)、ワーカータイプ、NGINX との連携、systemd 等での運用パターンを理解した上で、アプリの特性に合わせたワーカー選定・チューニングを行えば、堅牢なプロダクション環境を構築できます。一方、WebSocket や高度な非同期要件がある場合は ASGI ベースのサーバー選定も検討してください。


