DjangoプロジェクトをUbuntuにデプロイする方法をご紹介します。
nginxとuWSGIを用いて動作するように設定します。
目次
条件
- Ubuntu 16.04 LTS。(Ubuntu 18.04 LTSでも確認済み)
- Nginxがインストール済み。
- Djangoプロジェクトが存在する。
(Djangoプロジェクト作成済み、またはgitからクローン済み)
uWSGIのインストール
uWSGIとは?
WebサーバーとDjangoアプリケーションは直接対話することができません。
そこでWSGI(Web Server Gateway Interface)がWebサーバーとDjangoアプリケーションの橋渡しを行います。
WSGIは、WebサーバーとPythonアプリケーション間のインターフェースを規定している仕様です。
この仕様にのっとって実装されたものがuWSGIです。
インストール実行
python 2.xの場合
$ sudo pip install uwsgi
python 3.xの場合
$ sudo pip3 install uwsgi
インストール確認
$ uwsgi --version 2.0.17.1
python 2.xの場合
$ pip list ・・ uWSGI (2.0.17.1) ・・
python 3.xの場合
$ pip3 list ・・ uWSGI (2.0.17.1) ・・
簡単な動作確認
「Hello World」と表示させる簡単なプログラムを用いて簡単な動作確認を行います。
テストプログラム作成
test.pyを作成します。
$ cd ~/djangoTest/mysite $ vi test.py
ファイルの内容は以下の通りです。
# test.py def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"] # python3
動作確認実行
以下のコマンドを実行します。
$ cd ~/djangoTest/mysite $ uwsgi --http :8000 --wsgi-file test.py
このコマンドは以下の意味となります。
- HTTPプロトコルでポート8000を使用して通信する。
- その際の処理はtest.pyに記述された内容を使用する。
ブラウザで以下のURLを確認します。(サーバー内部からアクセスする場合)
http://127.0.0.1:8000/
以下のように表示されればOKです。
サーバー外部からアクセスを行う場合、ブラウザで以下のURLを確認します。(IPが123.45.67.89の場合)
http://123.45.76.89:8000/
現在の構成は以下の通りです。
the web client <-> uWSGI <-> Python
Djangoプロジェクトでの動作確認
今度はtest.pyではなく、Djangoプロジェクトでの動作確認を行います。
$ cd ~/djangoTest/mysite $ uwsgi --http :8000 --module mysite.wsgi
ブラウザにアクセスして想定通りに表示されればOKです。
サーバー外部からアクセスを行う場合、settings.pyに以下の設定が必要です。(IPが123.45.67.89の場合)
ALLOWED_HOSTS = ['123.45.67.89']
サーバー外部からアクセスを行う場合、ブラウザで「http://123.45.67.89/polls/」を指定します。
(アクセスURLはプロジェクト毎に読み替えてください。)
現在の構成は以下の通りです。
the web client <-> uWSGI <-> Django
nginxの設定
nginxのインストールについてはこちらをご確認ください。
nginxの動作確認
ブラウザで以下のURLにアクセスして「Welcome to nginx!」と表示されればOKです。
http://127.0.0.1:80
uwsgi_paramsのコピー
/etc/nginx/uwsgi_params を Djangoプロジェクトmysiteディレクトリにコピーします。
コピー元
/etc/nginx$ ls -ltr 合計 48 -rw-r--r-- 1 root root 3610 4月 18 00:22 win-utf -rw-r--r-- 1 root root 664 4月 18 00:22 uwsgi_params -rw-r--r-- 1 root root 636 4月 18 00:22 scgi_params -rw-r--r-- 1 root root 5170 4月 18 00:22 mime.types -rw-r--r-- 1 root root 2223 4月 18 00:22 koi-win -rw-r--r-- 1 root root 2837 4月 18 00:22 koi-utf -rw-r--r-- 1 root root 1007 4月 18 00:22 fastcgi_params -rw-r--r-- 1 root root 643 4月 18 00:59 nginx.conf.bak lrwxrwxrwx 1 root root 22 4月 18 01:00 modules -> /usr/lib/nginx/modules drwxr-xr-x 2 root root 4096 9月 24 12:35 conf.d -rw-r--r-- 1 root root 4600 9月 24 12:54 nginx.conf
コピー後の状態(uwsgi_paramsをコピーした状態)
/djangoTest/mysite$ ls MyDatabase manage.py mysite polls templates test.py uwsgi_params venv
nginx参照設定
Djangoプロジェクトにコピーしたuwsgi_paramsをnginxが参照するよう以下を実施します。
Djangoプロジェクトにmysite_nginx.confを作成
$ sudo vi ~/djangoTest/mysite/mysite_nginx.conf
以下の設定ファイルのパス等は、自分の環境に合った値に編集します。(mysite_nginx.conf)
# the upstream component nginx needs to connect to upstream django { # server unix:///path/to/your/mysite/mysite.sock; # for a file socket server 127.0.0.1:8001; # for a web port socket (we'll use this first) } # configuration of the server server { # the port your site will be served on listen 8000; # the domain name it will serve for server_name example.com; # substitute your machine's IP address or FQDN charset utf-8; # max upload size client_max_body_size 75M; # adjust to taste # Django media location /media { alias /path/to/your/mysite/media; # your Django project's media files - amend as required } location /static { alias /path/to/your/mysite/static; # your Django project's static files - amend as required } # Finally, send all non-media requests to the Django server. location / { uwsgi_pass django; include /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed } }
シンボリックリンク
シンボリックリンクを/usr/local/etc/nginx/sites-enabled/に貼ります。
⇒nginxがmysite_nginx.confを参照出来るようになります。
$ sudo mkdir /etc/nginx/sites-enabled $ sudo ln -s ~/djangoTest/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
設定ファイルの参照確認
nginxの起動時にどの設定ファイルが読み込まれているのか確認します。
/etc/nginx/nginx.conf を確認します。
(/etc/nginx/sites-enabled/*が読み込まれる設定になっているかを確認します。)
・・・ http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; # ←この記述が存在することを確認する。 ・・・
staticファイルのデプロイ
~/djangoTest/mysite/mysite/settings.py に以下の記述を追加します。
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
~/djangoTest/mysite で以下のコマンドを実行します。
$ python3 manage.py collectstatic
すると~/djangoTest/mysiteの下にstaticディレクトリが作成されます。
~/djangoTest/mysite$ ls MyDatabase manage.py mysite mysite_nginx.conf polls static templates test.py uwsgi_params venv
設定の反映
nginxを再起動します。
$ sudo service nginx restart
nginxとtest.pyの対話確認
以下のコマンドを実行してtest.pyとnginxが対話できることの確認を行います。
$ cd ~/djangoTest/mysite $ uwsgi --socket :8001 --wsgi-file test.py
以下のURLを確認します。
http://127.0.0.1:8000/
以下のように表示されればOKです。
サーバー外部からアクセスを行う場合、ブラウザで以下のURLを確認します。(IPが123.45.67.89の場合)
http://123.45.76.89:8000/
現在の構成は以下の通りです。
the web client <-> the web server <-> the socket <-> uWSGI <-> Python
nginxとDjangoアプリケーションの対話確認
今度はtest.pyと同様、Djangoアプリケーションとnginxが対話できることの確認を行います。
$ cd ~/djangoTest/mysite $ uwsgi --socket :8001 --module mysite.wsgi
以下のように表示されればOKです。
サーバー外部からアクセスを行う場合、settings.pyに以下の設定が必要です。(IPが123.45.67.89の場合)
ALLOWED_HOSTS = ['123.45.67.89']
サーバー外部からアクセスを行う場合、ブラウザで「http://123.45.67.89/polls/」を指定します。
(アクセスURLはプロジェクト毎に読み替えてください。)
現在の構成は以下の通りです。
the web client <-> the web server <-> the socket <-> uWSGI <-> Django
TCPポートソケットの代わりにUnixソケットを使用
Unixソケットの方がオーバーヘッドが少なくて済むため、Unixソケットを使用するよう設定します。
mysite_nginx.conf を以下のように編集します。
(パスを訂正しコメントアウトを付け直します)
$ cd ~/djangoTest/mysite $ sudo vi mysite_nginx.conf
以下のように設定します。
# the upstream component nginx needs to connect to upstream django { server unix:///home/username/djangoTest/mysite/mysite.sock; # for a file socket # server 127.0.0.1:8001; # for a web port socket (we'll use this first) } ・・・
nginxを再起動して設定を反映します。
$ sudo service nginx restart
uWSGIを起動してtest.pyで確認
以下のコマンドを実行します。
$ cd ~/djangoTest/mysite $ uwsgi --socket mysite.sock --wsgi-file test.py
以下のように「mysite.sock」が生成されます。
~/djangoTest/mysite$ ls MyDatabase mysite mysite_nginx.conf static test.py venv manage.py mysite.sock polls templates uwsgi_params
以下のURLを確認します。
http://127.0.0.1:8000/
エラーになりました。
エラーログ(/var/log/nginx/error.log)を確認したところ、/djangoTest/mysite/mysite.sock failed (13: Permission denied) というログが出力されていました。
権限に問題がありそうです。
そこで、パーミッションを指定してuWSGIを起動します。
$ uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
以下のURLを確認します。
http://127.0.0.1:8000/
以下のように表示されればOKです。
uWSGIを起動してDjangoアプリケーションで確認
以下のコマンドを実行します。
$ cd ~/djangoTest/mysite $ uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666
以下のように表示されればOKです。
iniファイルによる設定
iniファイルにuWSGIの各種設定を記述することで起動コマンドを簡略化します。
mysite_uwsgi.ini ファイルを作成します。
$ sudo vi ~/djangoTest/mysite/mysite_uwsgi.ini
内容は以下の通りです。
自分の環境に合わせて編集します。
[uwsgi] # Django-related settings # the base directory (full path) chdir = /path/to/your/project # Django's wsgi file module = project.wsgi # the virtualenv (full path) home = /path/to/virtualenv # process-related settings # master master = true # maximum number of worker processes processes = 10 # the socket (use the full path to be safe socket = /path/to/your/project/mysite.sock # ... with appropriate permissions - may be needed # chmod-socket = 664 # clear environment on exit vacuum = true
今回は以下のように設定しました。
[uwsgi] # Django-related settings # the base directory (full path) chdir = /home/username/djangoTest/mysite # Django's wsgi file module = mysite.wsgi # the virtualenv (full path) # home = /path/to/virtualenv # process-related settings # master master = true # maximum number of worker processes processes = 10 # the socket (use the full path to be safe socket = /home/username/djangoTest/mysite/mysite.sock # ... with appropriate permissions - may be needed chmod-socket = 666 # clear environment on exit vacuum = true
以下のコマンドを実行します。
(作成したiniファイルを指定してuWSGIを起動します)
$ cd ~/djangoTest/mysite $ uwsgi --ini mysite_uwsgi.ini
以下のように表示されればOKです。
起動、停止、確認コマンド
バックグラウンド起動
$ cd ~/djangoTest/mysite $ uwsgi --ini mysite_uwsgi.ini &
☆「&」を付けてコマンドを実行します。
プロセス確認
$ ps -aux | grep uwsgi
例)
server@XXX-XX-XX-XX:~/djangoTest/mysite$ ps -aux | grep uwsgi server 1636 10.0 4.2 131196 42724 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1638 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1639 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1640 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1641 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1642 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1643 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1644 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1645 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1646 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1647 0.0 3.1 131196 31852 pts/0 S+ 11:31 0:00 uwsgi --ini mysite_uwsgi.ini server 1649 0.0 0.0 13136 1000 pts/1 S+ 11:31 0:00 grep --color=auto uwsgi server@XXX-XX-XX-XX:~/djangoTest/mysite$
プロセス停止
$ kill -QUIT マスタプロセスのPID
☆プロセスの削除は「マスタプロセス」(一番上)のみkillすればすべて消えます。
例)
server@XXX-XX-XX-XX:~/djangoTest/mysite$ ps -aux | grep uwsgi server 1755 4.5 4.1 130052 41820 pts/0 S+ 11:54 0:00 uwsgi --ini mysite_uwsgi.ini server 1757 0.0 3.1 130052 32004 pts/0 S+ 11:54 0:00 uwsgi --ini mysite_uwsgi.ini server 1759 0.0 0.1 13136 1048 pts/1 S+ 11:54 0:00 grep --color=auto uwsgi server@XXX-XX-XX-XX:~/djangoTest/mysite$ server@XXX-XX-XX-XX:~/djangoTest/mysite$ kill -QUIT 1755 server@XXX-XX-XX-XX:~/djangoTest/mysite$ ps -aux | grep uwsgi server 1762 0.0 0.0 13136 1004 pts/1 S+ 11:55 0:00 grep --color=auto uwsgi server@XXX-XX-XX-XX:~/djangoTest/mysite$
uWSGIのログ出力設定
ログ出力先ディレクトリ作成
以下のコマンドで、ログ出力先ディレクトリ作成&アクセス権設定を行います。
sudo mkdir /var/log/uwsgi sudo chmod o+w /var/log/uwsgi
ログ出力先の指定
mysite_uwsgi.iniに以下を追記してログ出力先を指定します。
$ cd ~/djangoTest/mysite $ sudo vi mysite_uwsgi.ini
# logging logto = /var/log/uwsgi/mysite.log
uWSGIを起動すると、指定したパスへログが出力されるようになります。
ログローテーション設定
ログローテーション設定ファイル作成
ログローテーション設定のディレクトリに移動し、uwsgi用の設定ファイルを作成します。
(内容は適宜変更してください。)
$ cd /etc/logrotate.d $ sudo vi uwsgi
以下は1日ごとにログローテーションを行い、古いログには末尾に年月日を付ける設定です。
/var/log/uwsgi/mysite.log { daily rotate 5 missingok notifempty copytruncate dateext dateformat %Y-%m-%d }
設定反映
以下のコマンドを実行して設定を反映します。
sudo /usr/sbin/logrotate /etc/logrotate.conf
参考
以下のサイトを参考にさせて頂きました。
https://qiita.com/Ningensei848/items/e91fbeef5f03685a7a0b
https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html