VPSにおけるDjangoとnginxのセットアップ

サマリ

Djangoで作成したWebアプリをVPS上でuWSGI/nginxで動かすためのセットアップまとめ。
初心者が初めてセットアップした時のメモですので、とりあえず動かすために必要最低限なことをやってみたという内容です。
基本はこのチュートリアルのなぞりです。

ちなみにVPSはConoHaのメモリ1GB, CPU 2Core, SSD 50GBで月額900円(税抜)をお借りしました。OSはUbuntu 16.04をインストールしています。

前提

  • ローカルで動作可能なDjangoプロジェクトを作成済
  • 適当なサーバ(VPSなど)を入手済でコマンドライン操作できる

予め理解しておくべきこと

今回キーになるソフトウェアは以下の3つ。

  • Python製WebフレームワークのDjango
  • Webサーバであるnginx
  • Djangoとnginxを繋ぐuWSGI

uWSGIはWSGIの実装(ややこしいがuWSGIはソフト、WSGIは仕様)。ざっくりいえば以下のような構成になる。

1
Web browser --- (Internet) --- nginx --- uWSGI --- Django(YourWebApp)

既にDjangoプロジェクトはローカルでは動作可能になっているはずなので、
肝はuWSGIでnginxとDjangoをうまく繋げてやることになります。

下準備

Django/uWSGIのインストール

まずサーバ上でのPythonの環境構築と必要なソフトのインストールから。
ここではpyenvpyenv-virtualenvを使います。
pyenvでPython 3.6.7をインストール済とします。

1
2
3
4
5
6
7
8
9
10
# Setup virtual-env
cd $HOME
mkdir mysite
cd mysite
pyenv virtualenv 3.6.7 mysite
pyenv local mysite

# Install
pip install --upgrade pip
pip install django uwsgi

pip freezeをするとDjango==2.1.5uWSGI==2.0.18がインストールされたことが分かります。

Djangoプロジェクトの配置

私の場合、Djangoで作成したWebアプリのソースはGitHub上にあり、
VPS側ではgit clone(or pull)だけして使うようにしているので以下を実行します。
ゼロから作るときはdjango-admin startproject myprojなどとする箇所に該当します。

1
2
3
4
5
6
7
8
cd ~/mysite
git clone <repository URL>
cd <repository directory>

# とりあえずローカルで動くことを確認
python manage.py runserver 7999
# 別ターミナル上で
curl http://localhost:7999

とりあえずpython manage.py runserverでローカルで動くことを確認。
末尾のポート番号(ここでは7999)は適当に空いているものを。指定しなければデフォルトの8000になります。

以降、Djangoのプロジェクトディレクトリ名をmyproj、Webアプリのディレクトリ名をmyappと仮定して記載します。以下のような構成です。

1
2
3
4
5
6
~/mysite$ tree myproj -L 1
myproj
├── config
├── myapp
├── db.sqlite3
└── manage.py

Djangoのデフォルトではconfigに該当するディレクトリ名はmyproj(プロジェクト名と同名)になりますが、同名はややこしいのでconfigにしています。
そういうベストプラクティス構成の作り方はこちらの書籍を参考にしました。

nginxのインストール

最後にnginxのインストールですが、apt-getのみです。
インストール後、OS再起動すれば起動時に自動起動するようになっています。

1
sudo apt-get install nginx

nginxとuWSGIを繋げる設定

ここが実質的にメインの内容です。設定ファイルとしては2つ存在します。

uwsgi_params

まず、/etc/nginx/uwsgi_paramsというファイルがあるのでそれをmyprojにコピーします。これは変更不要です。

1
cp /etc/nginx/uwsgi_params ~/mysite/myproj/

nginx.conf

また、~/mysite/myproj/mysite_nginx.confというファイルを作りここの内容をコピペ。ただし以下は書き換えます。

  • serverブロックのlisten(基本は80でよい)
  • serverブロックのserver_name
  • /path/to...となっている箇所全て

server 127.0.0.1:8001という行がありますが、nginxはuWSGIとの通信に8001番ポートを使うということですので覚えておきます。
/path/to/...の箇所は、環境変数がそのままでは使えないので(使う方法はあるようです)とりあえず絶対パスで書きました。

そしてnginxが起動時にmysite_nginx.confを読み込むようにします。シンボリックリンクを貼ります。

1
sudo ln -s ~/mysite/myproj/mysite_nginx.conf /etc/nginx/enabled/

uWSGIの起動

あとはuWSGIを起動すればいいだけです。

1
2
3
cd ~/mysite/myproj
uwsgi --socket :8001 --module config.wsgi &
sudo service nginx restart # nginx再起動

uwsgiの--socketの箇所を--httpと書いてある説明もあるので混同しないように注意ください。
どちらも間違いでは無いようですが、--httpオプションでuWSGIを起動する場合はmysite_nginx.conflocationブロックのuwsgi_passディレクティブが変更必要です。

また、--module config.wsgiconfigディレクトリのwsgi.pyを指しています。うまく行かない場合はファイルが確かに存在するか確認します。(上で述べたとおり、configディレクトリの名称はDjangoのデフォルト設定ならばプロジェクト名と同名になっているので注意します)。

もうブラウザで見れるはず

DjangoアプリはuWSGIが起動してくれるので、ローカルサーバで動かす時のようなpython manage.py runserverの類は不要です。つまり、uWSGIとnginxが起動した今、既にWebサイトがブラウザで閲覧できるはずです。
当然ですが80番ポートがファイアウォールで閉じられていないかはご確認ください。

うまく出来ない場合

/var/log/nginxaccess.logerror.logを読みます。
私も幾つかハマりましたが、エラーログをよく読めばたいてい解決できました。