Django アプリのデプロイ(Gunicorn + Nginx)
『Djangoアプリのデプロイ(Gunicorn + Nginx)』は、Python の Web フレームワーク Django を本番環境へ公開するための標準的な手順です。virtualenv で Python 環境を隔離し、WSGI サーバーである Gunicorn をアプリケーションサーバーとして起動します。Gunicorn は systemd サービスとして登録することで OS 起動時に自動起動・クラッシュ時に自動再起動できます。Nginx をリバースプロキシとして前段に置くことで、静的ファイルの高速配信・SSL 終端・ポート 80/443 での公開を実現します。
構文
# ===============================================
# Django デプロイの全体フロー
# ===============================================
# -----------------------------------------------
# [Step 1] virtualenv で Python 仮想環境を作成する
# -----------------------------------------------
# virtualenv をインストールします(インストール済みの場合は不要です)
sudo apt install python3-venv
# プロジェクトディレクトリに移動します
# ここではプロジェクト名を "okabe-lab" とします
cd /var/www/okabe-lab
# 仮想環境を作成します(venv というディレクトリに作成されます)
python3 -m venv venv
# 仮想環境を有効化します
# プロンプトの先頭に (venv) が付けば有効化されています
source venv/bin/activate
# Django と Gunicorn をインストールします
pip install django gunicorn
# -----------------------------------------------
# [Step 2] Django の設定を本番用に変更する
# -----------------------------------------------
# settings.py の主要な本番設定
# DEBUG = False
# ALLOWED_HOSTS = ['example.com', 'www.example.com']
# STATIC_ROOT = '/var/www/okabe-lab/staticfiles/'
# 静的ファイルを STATIC_ROOT に収集します
python manage.py collectstatic
# データベースのマイグレーションを実行します
python manage.py migrate
# -----------------------------------------------
# [Step 3] Gunicorn の動作を手動で確認する
# -----------------------------------------------
# Gunicorn を手動起動して動作を確認します
# {プロジェクト名}.wsgi:application の形式で指定します
# --bind で Unix ソケットファイルのパスを指定します
gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock okabe_lab.wsgi:application
# 動作確認後は Ctrl+C で停止します
# -----------------------------------------------
# [Step 4] systemd サービスとして登録する
# -----------------------------------------------
# /etc/systemd/system/okabe-gunicorn.service を作成します(下記「使用例」参照)
# デーモンの設定を再読み込みします
sudo systemctl daemon-reload
# サービスを起動して OS 起動時の自動起動を有効化します
sudo systemctl start okabe-gunicorn
sudo systemctl enable okabe-gunicorn
# -----------------------------------------------
# [Step 5] Nginx リバースプロキシを設定する
# -----------------------------------------------
# /etc/nginx/sites-available/okabe-django.conf を作成します(下記「使用例」参照)
# sites-enabled にシンボリックリンクを作成して設定を有効化します
sudo ln -s /etc/nginx/sites-available/okabe-django.conf \
/etc/nginx/sites-enabled/
# Nginx の設定構文を確認してからリロードします
sudo nginx -t
sudo systemctl reload nginx
構文一覧
| 手順 | 説明 |
|---|---|
| 仮想環境の作成 | python3 -m venv venv でプロジェクト専用の Python 環境を作成します。システム全体の Python に影響を与えず、パッケージのバージョン管理が容易になります。 |
| 仮想環境の有効化 | source venv/bin/activate で仮想環境を有効化します。プロンプト先頭に (venv) が表示されれば有効化されています。 |
| パッケージのインストール | pip install django gunicorn で Django と Gunicorn を仮想環境内にインストールします。pip freeze > requirements.txt で依存関係を記録しておくことを推奨します。 |
| 静的ファイルの収集 | python manage.py collectstatic で Django の静的ファイルを STATIC_ROOT に収集します。Nginx が直接配信するため本番環境では必須の手順です。 |
| DB マイグレーション | python manage.py migrate でデータベーススキーマを最新状態に適用します。デプロイのたびにマイグレーションがないか確認する習慣をつけてください。 |
| Gunicorn の手動起動確認 | gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock {プロジェクト}.wsgi:application で動作を確認します。systemd 登録前に必ず手動で起動できることを確かめてください。 |
| systemd サービス作成 | /etc/systemd/system/{サービス名}.service にユニットファイルを作成します。WorkingDirectory と ExecStart にプロジェクトの絶対パスを正確に記述します。 |
| デーモンのリロード | sudo systemctl daemon-reload でユニットファイルの変更を systemd に認識させます。サービスファイルを編集したあとは必ず実行してください。 |
| サービスの起動と自動起動 | sudo systemctl start {サービス名} で起動し、sudo systemctl enable {サービス名} で OS 起動時の自動起動を登録します。 |
| Nginx 設定ファイルの作成 | /etc/nginx/sites-available/ に設定ファイルを作成し、proxy_pass で Gunicorn の Unix ソケットを指定します。 |
| Nginx 設定の有効化 | sudo ln -s /etc/nginx/sites-available/{設定ファイル} /etc/nginx/sites-enabled/ でシンボリックリンクを作成し設定を有効化します。 |
| Nginx 設定の検証とリロード | sudo nginx -t で構文エラーがないことを確認してから sudo systemctl reload nginx でリロードします。 |
使用例
Gunicorn の systemd サービス設定
# -----------------------------------------------
# /etc/systemd/system/okabe-gunicorn.service
# -----------------------------------------------
# 岡部倫太郎の Django プロジェクト "okabe-lab" を
# Gunicorn で起動するための systemd ユニットファイルです
[Unit]
# サービスの説明文です(journalctl 等で表示されます)
Description=Gunicorn daemon for okabe-lab (Rintaro Okabe's Django Project)
# ネットワークが利用可能になってから起動します
After=network.target
[Service]
# Gunicorn プロセスを実行するユーザーとグループを指定します
# www-data は Nginx が動作するデフォルトのユーザーです
User=www-data
Group=www-data
# Django プロジェクトのルートディレクトリを指定します
# manage.py が置かれているディレクトリです
WorkingDirectory=/var/www/okabe-lab
# 仮想環境の Gunicorn を使ってアプリを起動します
# --workers: CPU コア数 × 2 + 1 が推奨値です(ここでは 3 ワーカー)
# --bind: Nginx との通信に Unix ソケットを使用します(TCP より高速です)
# okabe_lab.wsgi:application: {Djangoプロジェクト名}/wsgi.py の application を指します
ExecStart=/var/www/okabe-lab/venv/bin/gunicorn \
--workers 3 \
--bind unix:/run/okabe-gunicorn.sock \
okabe_lab.wsgi:application
# プロセスが異常終了した場合に自動で再起動します
Restart=on-failure
[Install]
# multi-user.target: 通常のマルチユーザーモードで自動起動します
WantedBy=multi-user.target
/etc/nginx/sites-available/okabe-django.conf
# -----------------------------------------------
# /etc/nginx/sites-available/okabe-django.conf
# -----------------------------------------------
# Nginx が Gunicorn へリクエストを転送するための
# リバースプロキシ設定です
server {
# HTTP リクエストをポート 80 で受け付けます
listen 80;
# このサーバーブロックが対応するドメイン名を指定します
server_name okabe-lab.example.com;
# -----------------------------------------------
# 静的ファイルの直接配信
# -----------------------------------------------
# Django の collectstatic で収集したファイルを
# Gunicorn を介さず Nginx が直接配信します(高速化のため)
location /static/ {
alias /var/www/okabe-lab/staticfiles/;
}
# メディアファイル(ユーザーアップロード画像等)も直接配信します
location /media/ {
alias /var/www/okabe-lab/media/;
}
# -----------------------------------------------
# Gunicorn へのリバースプロキシ
# -----------------------------------------------
location / {
# Unix ソケット経由で Gunicorn にリクエストを転送します
proxy_pass http://unix:/run/okabe-gunicorn.sock;
# 接続先のホスト名をバックエンドに伝えます
proxy_set_header Host $host;
# クライアントの本来の IP アドレスを伝えます
proxy_set_header X-Real-IP $remote_addr;
# プロキシを経由していることをバックエンドに伝えます
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# プロトコル(http/https)をバックエンドに伝えます
proxy_set_header X-Forwarded-Proto $scheme;
}
}
実行するコマンドは次の通りです。
$ sudo systemctl daemon-reload
$ sudo systemctl start okabe-gunicorn
$ sudo systemctl enable okabe-gunicorn
Created symlink /etc/systemd/system/multi-user.target.wants/okabe-gunicorn.service → /etc/systemd/system/okabe-gunicorn.service.
$ sudo systemctl status okabe-gunicorn
● okabe-gunicorn.service - Gunicorn daemon for okabe-lab (Rintaro Okabe's Django Project)
Loaded: loaded (/etc/systemd/system/okabe-gunicorn.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-03-25 10:15:30 JST; 3s ago
Main PID: 12345 (gunicorn)
Tasks: 4 (limit: 4612)
Memory: 72.4M
CPU: 831ms
CGroup: /system.slice/okabe-gunicorn.service
├─12345 /var/www/okabe-lab/venv/bin/python /var/www/okabe-lab/venv/bin/gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock okabe_lab.wsgi:application
├─12346 /var/www/okabe-lab/venv/bin/python /var/www/okabe-lab/venv/bin/gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock okabe_lab.wsgi:application
├─12347 /var/www/okabe-lab/venv/bin/python /var/www/okabe-lab/venv/bin/gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock okabe_lab.wsgi:application
└─12348 /var/www/okabe-lab/venv/bin/python /var/www/okabe-lab/venv/bin/gunicorn --workers 3 --bind unix:/run/okabe-gunicorn.sock okabe_lab.wsgi:application
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx
$ curl -s -o /dev/null -w "%{http_code}" http://okabe-lab.example.com/
200
概要
Django アプリの本番デプロイでは「virtualenv による環境隔離 → Gunicorn による WSGI サービング → systemd による プロセス管理 → Nginx によるリバースプロキシ」という 4 層構成が定番です。virtualenv を使うことでシステムの Python 環境を汚さずにプロジェクトごとの依存パッケージを管理できます。Gunicorn はマルチワーカープロセスで並列リクエストを処理しますが、HTTP サーバー機能が限定的なため、静的ファイル配信・SSL 終端・ポート 80/443 への対応を Nginx に任せるのが定石です。systemd へのサービス登録については systemd ユニットファイル のページで詳しく解説しています。Nginx のリバースプロキシ設定の詳細は Nginx リバースプロキシ のページを参照してください。Unix ソケット(『unix:/run/okabe-gunicorn.sock』)を使うことで、TCP ポートを消費せずにプロセス間通信を行えるため、同一サーバー上の Gunicorn ↔ Nginx 間の通信に適しています。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。