上記の記事の続きです。
前回は VPS の中に Nginx を使用して Web サーバを構築し、リクエストを送るとレスポンスが返ってくるところまで行いました。

WEB 3層構成
目的は題名の通り、Django で作った WEB アプリケーションを VPS で公開することです。
そのためには下記のような WEB 3層構成(WEB 3層構造)を構築していきます。
下の段にある Webサーバ・APサーバ・DBサーバそれぞれが別の種類のサーバです。
サーバとはリクエストに対してレスポンスを返すものでした。
これら3つはそれぞれ別の種類のリクエストを受け取り、
別の種類のレスポンスを返します。
Web サーバ | Nginx, Apache | 静的ページを扱う |
AP サーバ | Django, Laravel, Ruby on Rails | 動的ページを扱う |
DB サーバ | MySQL, SQLite, MariaDB, PostgreSQL | データベースの管理 |
動的ページとは、同じ URL なのに見る人で違う内容が表示されるものです。
例えば Twitter のタイムライン。
タイムラインのページは全員同じ https://twitter.com/home です。
URL は同じですが、アカウント毎に表示が違います。
静的ページは誰が見ても同じ内容のページです。
Twitter の サービス利用規約 は誰が見ても同じです。
これは静的ページに当たります。
静的ページしか扱えない Nginx だけでは Twitter のサービス利用規約の表示はできますが、タイムラインを表示できません。
タイムラインは AP サーバを利用してレスポンスを返しています。
runserver による接続
先ほどの WEB 3層構成をそのまま構築します。
いつものようにmange.py runserver
を行い、IPアドレスにアクセスがあった際に Nginx からそのページに飛ばす、という接続方法です。
DBサーバに関しては既に①で設定済みです。
今回は Nginx の Web サーバと Django で立ち上げる AP サーバの接続を行います。
Nginx / 設定ファイルの編集
location / { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X_Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:8000; }
Django / settings.py の編集
settings.py の編集が必要なのはドメインを取得して利用している場合です。
ALLOWED_HOSTS は Django (アプリケーションサーバ)に誰が接続できるかを設定します。
ALLOWED_HOSTS = ['借りているIPアドレス', 'localhost']
このページの通りに来ている場合は上記の内容になっていると思います。
取得したドメインが example.com の場合、
APサーバに接続するのは example.com になります。
example.com は上記の内容に含まれていないためアクセスができず、
Webサーバ → APサーバ間でエラーが起きます。
ALLOWED_HOSTS = ['借りているIPアドレス', 'localhost', 'example.com']
'example.com'
を追加することでエラーを回避できます。
runserver
- python の仮想環境に入る
- manage.py のディレクトリに移動
上記を行ったうえで、いつもどおり runserver を行います。
python3 manage.py runserver
これで Chrome などのウェブブラウザから IP アドレスにアクセスすると Django で設定しているページに飛べるはずです。
エラーが出る場合
前回の静的ファイルのレスポンスが問題なくできていたのであれば、リクエストは Nginx まで無事に届いています。
今回新しく追加した部分でエラーが起こっていることになります。

エラーが発生するケースは大きく分けると 3つです。
- runserver が起動しないエラー
- Nginx -> Django でのリクエストが届かないエラー
- Django ↔ MariaDB 間でのエラー
エラーを検証していく前に確認しておきたいのが
ローカルでエラーが起きていないかという部分です。
サーバでエラーが発生し、ローカルでも同様のエラーが発生する場合、まずは必ずローカル環境を見直してください。
疑いのあるエラー箇所が多すぎるため、消去法で消していくほかありません。
① runserver が起動しないエラー
python3 manage.py runserver
を行った際に
コンソールに何らかのエラー文がでるはずです。
下記の疑いがあります。比較的わかりやすく、対応もすぐできます。
- manage.py とは違う階層で runserver を行っている
- 仮想環境に入っていない
- Django がインストールできてない / バージョンが違う
② Nginx → Django のエラー
Nginx から Django への接続ができていない場合です。

この場合、Django のページやエラーのページなどが一切表示されず、
下記のような Nginx のページが表示される場合です。

これはリクエストが Django に届いていない状況です。
Nginx 側の設定ファイルやディレクトリ構造を見直してください。
- 設定ファイルの記述が間違っている
- ディレクティブの末尾の「 ; 」が抜けている
- sites-abairable に設定ファイルが置かれていない
- sites-enabled にシンボリックリンクが置かれていない
- nginx.conf や設定ファイルに構文エラーがある
- IPアドレスやドメイン名が間違っている
- プロキシの文が間違っている
などです。
私の場合はデバッグ用のシンプルな html を表示させるビューを用意しています。
そのビューが表示されればリクエストが AP サーバまで届いているし、表示されなれば AP サーバまで渡っていません。
下記のコードで nginx.conf に不備がないか確認できます。
sudo nginx -t
下記の文が出力されていれば問題ありません。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
③ Django → Nginx のエラー
Django からのレスポンスが返ってこない場合です。

ページは表示されるけれど、何かしらのアクションを行った際にエラーでとまるケースです。
ポイントはデータベースにアクセスしないページを表示することです。
例えば管理画面を表示しようとした場合、
- データベースにアクセスできないエラー
- データベースからデータを持ってこれない場合のエラー
など、DBサーバ側のエラーの疑いが含まれます。
ここでエラーが起きている場合は Django の内部でのエラーです。
- settings.py の DEBUG を True にしてみる
- pip でインストールが必要なライブラリが揃っていない
- PyTorch をローカルと同じ方法でインストールしている
- migrate をしていない
- Git へのプッシュ / プルが正確にできてない
- 100 MB を超えるファイルに対してLFS のプルを行っていない
など、他の可能性も含めて疑いのある原因は多いです。
この場合は settings.py の DEBUG を True にすることでエラー内容を確認できます。
まだ公開していない場合やテストサーバの場合は True にしてエラー文を見てみることをお勧めします。
④ Django ↔ MariaDB のエラー
データベースを読みに行ってエラーが発生する場合はデータベースサーバでエラーが発生しています。

ローカルで動いているのであれば、Django とデータベースの接続はできているはずです。
サーバの環境でデータベースサーバとうまく連携されていない可能性が高いため、下記を確認してみてください。
- サーバ側の settings.py の DATABASE の設定が間違っている
- データベースのインストールがされていない
- データベースのアカウントを作っていない
Gunicorn
runserver で起動した場合は一時的な起動しかできません。
VPS のコンソールからログアウトした段階で接続が切れます。
そのため、runserver は起動確認などでのみ利用します。
実際の運用時には Gunicorn をNginx と Django の間に入れ、
Gunicorn をアプリケーションサーバとして利用します。

Gunicorn とは
Gunicorn は WSGI規格に準拠した AP サーバのひとつです。
WSGI
インストール
Gunicorn は pip で仮想環境にインストールします。
仮想環境に入っていない場合は仮想環境に入ってからインストールします。
workon 環境名
pip install gunicorn
Gunicorn の使い方
起動 | gunicorn --bind 127.0.0.1:8000 プロジェクト名.wsgi |
バックグラウンド (デーモンモード)で起動 | gunicorn --bind 127.0.0.1:8000 プロジェクト名.wsgi -D |
プロセスの確認 | ps ax | grep gunicorn |
停止 | pkill gunicorn |
-D
はデーモンモードで Gunicorn を実行するコマンドです。バックグラウンドで Gunicorn が起動します。
デーモン
デーモンは Linux の常駐プログラムを指します。
先ほどもお伝えしましたが、Django は runserver を起動したときしか AP サーバとして稼働しないため、常駐させられません。
Gunicorn もデフォルトの起動方法ではデーモン化しません。
(この表現合ってるんでしょうか)
Gunicorn は -D を付けることでデーモンモ常駐してくれるようになります。
Supervisor を使用して Gunicorn を常駐化させるチュートリアルもありましたが、こちらは私は試していません。
http と ソケット接続
Nginx と Gunicorn を接続するには http 接続とソケット接続の2種類があります。
http接続 | 構成変更がしやすい・簡単 |
ソケット接続 | 早い |
http 接続
Nginx の設定ファイル
http 接続は受け取ったリクエストを自身の 8000番ポートへ接続します。
runserver の時と同じ内容です。
location / { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X_Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:8000; }
接続
ここまでのすべてのエラーを解消していれば、下記のコードで常駐する AP サーバが稼働します。
gunicorn --bind 127.0.0.1:8000 プロジェクト名.wsgi -D
Gunicorn の http 接続はかなり簡単です。インストールして起動するだけです。
ソケット接続
ソケット接続に関しては書きかけです。そのうち更新します。(たぶん)