はじめに
Setting up Django and your web server with uWSGI and nginx — uWSGI 2.0 documentationを適宜和訳しつつ、Djangoでつくったアプリをサーバーにデプロイしていこうと思います。
ここでいうサーバーは「EC2」でも「さくら」でもなくごく一般的なサーバマシンを想定します。
※ただし、uWSGIはWindowsには非対応です。どうしてもWindows上で使いたい場合、以下の記事にあるようにWSL(Windows Subsystem for Linux)をご利用の上、本記事を読み進めてください。
PyCharm + WSLを導入したWindows10でのDjango開発 - Qiita
introduction
This tutorial is aimed at the Django user who wants to set up a production web server. It takes you through the steps required to set up Django so that it works nicely with uWSGI and nginx. It covers all three components, providing a complete stack of web application and server software.
このチュートリアルは任意のwebサーバーに製品をセットアップしたいDjango使用者に焦点を当てています。DjangoがuWSGIとnginxでうまく動作するように、Djangoをセットアップする手順を説明します。
Some notes about this tutorial
(省略) 詳細は元のページを参照のこと
Concept
A web server faces the outside world. It can serve files (HTML, images, CSS, etc) directly from the file system. However, it can’t talk directly to Django applications; it needs something that will run the application, feed it requests from web clients (such as browsers) and return responses.
Webサーバーは外界に面し、静的ファイル(HTML、画像、CSSなど)をファイルシステムから直接処理することができます。 しかし、Djangoのアプリケーションと直接対話することはできません。 アプリケーションを実行し、Webクライアント(ブラウザなど)から要求をフィードして応答を返すものが必要です。
A Web Server Gateway Interface - WSGI - does this job. WSGI is a Python standard.
そこで、WSGI(Web Server Gateway Interface)がこの役割を担います。WSGI(ウィズギィー)はPythonにおける標準規格です。
uWSGI is a WSGI implementation. In this tutorial we will set up uWSGI so that it creates a Unix socket, and serves responses to the web server via the uwsgi protocol. At the end, our complete stack of components will look like this:
uWSGIはWSGIに則って実装されています。 このチュートリアルでは、uWSGIを設定してUnixソケットを作成し、uwsgiプロトコルを使用してWebサーバーへの応答を提供します。 結局、全体の構成は以下のようになります:
the web client <-> the web server <-> the socket <-> uwsgi <-> Django
Before you start setting up uWSGI
activate virtualenv & install latest Django
(訳者注:python3.3以降の標準であるvenvか、またはpipenvを使うべきかもしれませんが、このチュートリアルではそのままvirtualenvが使われているので適宜読み替えてください)
$ virtualenv uwsgi-tutorial
$ cd uwsgi-tutorial
uwsgi-tutorial/ $ source bin/activate
uwsgi-tutorial/ $ pip install Django
uwsgi-tutorial/ $ django-admin.py startproject mysite
uwsgi-tutorial/ $ cd mysite
uwsgi-tutorial/mysite/ $ # are you ready?
About the domain and port
In this tutorial we will call your domain
example.com
. Substitute your own FQDN or IP address.
このチュートリアルでは、あなたのドメインをexample.com
と呼ぶことにします。 これをあなたのFQDNまたはIPアドレスに置き換えて考えてください。
(訳者注:Linux機やWSLをご利用の場合、localhost
や127.0.0.1
を使うと良いでしょう。本記事は127.0.0.1
の想定で進めます)
Throughout, we’ll be using port 8000 for the web server to publish on, just like the Django runserver does by default. You can use whatever port you want of course, but I have chosen this one so it doesn’t conflict with anything a web server might be doing already.
私たちは、Django実行サーバーがデフォルトと同様にポート8000を使用しています。あなたはもちろんどんなポートでも使うことができますが、私たちはこのポートを選択していますので、Webサーバーがすでに行っている可能性のあるものと競合するかもしれません。
Basic uWSGI installation and configuration
Install uWSGI into your virtualenv
# $ sudo apt install python3.6-dev
uwsgi-tutorial/ $ pip install --upgrade pip # get latest pip
uwsgi-tutorial/ $ pip install uwsgi
uwsgi-tutorial/ $ pip freeze # confirm module list
'''
Django==2.0.3
pkg-resources==0.0.0
pytz==2018.3
uWSGI==2.0.17
'''
Of course there are other ways to install uWSGI, but this one is as good as any. Remember that you will need to have Python development packages installed. In the case of Debian, or Debian-derived systems such as Ubuntu, what you need to have installed is pythonX.Y-dev, where X.Y is your version of Python.
もちろん、uWSGIをインストールするには他の方法もありますが、これはほかと比べても同等に良い方法だと思います。なお、Python開発パッケージがインストールされている必要があることに注意してください。 DebianやUbuntuなどのDebian系システムの場合、インストールする必要があるのはpythonX.Y-devです.X.YはPythonのバージョンです。
Basic test
Create a file called
test.py
:
uwsgi-tutorial/mysite/ $ vi test.py # copy & paste contents below to this file
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] # python3
#return ["Hello World"] # python2
Run uWSGI:
uwsgi-tutorial/mysite/ $ uwsgi --http :8000 --wsgi-file test.py
The options mean:
http :8000
: use protocol http, port 8000
wsgi-file test.py
: load the specified file,test.py
オプションを使うことで、HTTPプロトコルを使って通信せよ、その際にポートは8000を使えという命令を出し、その際の処理はtest.py
に書いてあることを実行せよ、というふうにuWSGIに伝えています。
This should serve a ‘hello world’ message directly to the browser on port 8000. Visit:
http://example.com:8000
to check. If so, it means the following stack of components works:
the web client <-> uWSGI <-> Python
この接続によって、pythonは「hello world」をブラウザに直接ポート8000を通して返します。
http://127.0.0.1:8000
にアクセスして、正常に動作しているか確かめましょう。
動作していれば、「the web client(ブラウザ)」から「uWSGI」を通して「python(で書かれたプログラム)」が置かれたサーバーにアクセスできたことになります。
Test your Django project
Now we want uWSGI to do the same thing, but to run a Django site instead of the
test.py
module. If you haven’t already done so, make sure that your mysite project actually works:
uwsgi-tutorial/mysite/ $ python manage.py runserver
今度は、いまやったことをuWSGIにさせましょう。つまり、test.py
モジュールの代わりにuWSGIからDjangoサイトを実行するようにしたいと思います。なお、まだ動作確認を行なっていない場合は、上記コマンドを実行してmysiteプロジェクトが実際に動作することを確認してください:
(訳者注:Djangoの実行サーバーが正常に動作していることが確認できたら、Ctrl + C
で停止させてください)
And if that works, run it using uWSGI:
uwsgi-tutorial/mysite/ $ uwsgi --http :8000 --module mysite.wsgi
Djangoの実行サーバーが動いていることが確認できたら、今度はmysiteプロジェクトをuWSGIに動かさせてみましょう。上記コマンドを実行してください。
mysite.wsgi
: load the specified wsgi module
Point your browser at the server ; if the site appears, it means uWSGI is able to serve your Django application from your virtualenv, and this stack operates correctly:
the web client(ブラウザ) <-> uWSGI(仲介役) <-> Django
mysiteプロジェクト内部にあるmysite.wsgi
モジュール(mysite/mysite/wsgi.py)はブラウザにサーバーの方向を示します(?)。 サイトが表示されれば、uWSGIが(virtualenvから)Djangoアプリケーションを提供できることを意味しています。この時点で、全体の構成は上記のようになっています。
Now normally we won’t have the browser speaking directly to uWSGI. That’s a job for the web server, which will act as a go-between.
しかし通常はブラウザがuWSGIに直接やりとりすることはありません。 実際のところ、これはウェブサーバーの仕事であり、このままにしておけばuWSGIは中途半端な行動をとるでしょう。
Basic nginx
Install nginx
参考:Ubuntuに最新のnginxをインストールする - Qiita
# (1) nginxサイトが配布するPGPキーを追加
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
# (2) リポジトリを一覧に追加
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb-src http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
# (3) アップデート後、nginxをインストール
sudo apt update
sudo apt install nginx
# versionの確認
# nginx -V
# (4) nginxを起動
sudo /etc/init.d/nginx start # start nginx
'''
[ ok ] Starting nginx (via systemctl): nginx.service.
'''
参照:Nginxの更新履歴
And now check that nginx is serving by visiting it in a web browser on port 80 - you should get a message from nginx: “Welcome to nginx!”. That means these components of the full stack are working together:
the web client <-> the web server
http://127.0.0.1:80を訪問して、nginxがポート80のウェブブラウザでよしなにしてくれていることを確認しましょう。正常に動いていれば、"Welcome to nginx!"と表示されるはずです。これは、web client(ブラウザ) と web server(nginx)が連携できていることを意味します。
If something else is already serving on port 80 and you want to use nginx there, you’ll have to reconfigure nginx to serve on a different port. For this tutorial though, we’re going to be using port 8000.
他の何かがすでにポート80でサービスを提供場合、別のポートでサービスするようにnginxを再設定する必要があります。なお、このチュートリアルでは、ポート8000を使用します (訳者注:ので、それ以外のポートに設定 / 対象サービスを停止してください)。
Configure nginx for your site
You will need the
uwsgi_params
file, which is available in thenginx
directory of the uWSGI distribution, or from "nginx/uwsgi_params at master · nginx/nginx" - Github
ここで、uwsgi_params
ファイルが必要となります。これは、uWSGIディストリビューションの nginx
ディレクトリまたはこのリンクから入手することができます。
(訳者注:/ etc / nginx
ディレクトリ(nginxのパッケージがインストールされているディレクトリ)の直下にuwsgi_params
があればそれをmysite
以下にコピーしてください。もし存在しなければ以下をコピペしてmysite/uwsgi_params
をつくってください)
$ cd /etc/nginx
/etc/nginx/ $ ls -l
'''
total 36
drwxr-xr-x 2 root root 4096 Mar 31 13:14 conf.d
-rw-r--r-- 1 root root 1007 Oct 17 22:16 fastcgi_params
-rw-r--r-- 1 root root 2837 Oct 17 22:16 koi-utf
-rw-r--r-- 1 root root 2223 Oct 17 22:16 koi-win
-rw-r--r-- 1 root root 3957 Oct 17 22:16 mime.types
lrwxrwxrwx 1 root root 22 Oct 17 22:35 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root 643 Oct 17 22:34 nginx.conf
-rw-r--r-- 1 root root 636 Oct 17 22:16 scgi_params
-rw-r--r-- 1 root root 664 Oct 17 22:16 uwsgi_params # <=== this file
-rw-r--r-- 1 root root 3610 Oct 17 22:16 win-utf
'''
/etc/nginx/ $ vi uwsgi_params # open file to write this contents below
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
Copy it into your project directory. In a moment we will tell nginx to refer to it. Now create a file called mysite_nginx.conf in the /etc/nginx/sites-available/ directory, and put this in it:
プロジェクトディレクトリmysite
にこのファイルをコピーします(Djangoプロジェクトの構成ディレクトリのうち一番外側です)。 今はまだもう少しだけ、そこを参照するようにnginxに教えてあげています。
そしてさらに、もうひとつ/ etc / nginx / sites-available /
ディレクトリにmysite_nginx.conf
という名前のファイルを作成します。
(参考:Nginxのバーチャルホスト設定 - Qiita … )
$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled
$ cd /etc/nginx/sites-available
/etc/nginx/sites-available/ $ sudo vi 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
}
}
This conf file tells nginx to serve up media and static files from the filesystem, as well as handle requests that require Django’s intervention. For a large deployment it is considered good practice to let one server handle static/media files, and another handle Django applications, but for now, this will do just fine.
この設定ファイル(*.conf)は、nginxにファイルシステムのメディアと静的ファイルを提供し、Djangoの介入が必要なリクエストを処理するようにnginxに指定します。もしもプロジェクトが大規模な場合では、あるサーバが静的/メディアファイルを処理し、また別のサーバがDjangoアプリケーションを処理するようにする(訳者注:つまりその役割ごとにサーバを使い分ける)のが良い方法ですが、今のところ一つのサーバだけでうまくいくでしょう。
Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:
mysite_nginx.confをmysite以下へコピーし、そこからシンボリックリンクを張りましょう。
$ cp /etc/nginx/sites-available/mysite_nginx.conf ~/uwsgi-tutorial/mysite
$ sudo ln -s ~/uwsgi-tutorial/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
mysite_nginx.conf
から/etc/nginx/sites-enabled
へのシンボリックリンクを貼りましょう。そうすることで、web server としてのnginxがその設定ファイルを参照することが出来るようになります。(訳者注:コピペする前にパスの確認を!)
! Caution !
せっかく/etc/nginx/sites-enabled
へのシンボリックリンクを張っても、その先でmysite_nginx.conf
を読み込んでもらえねば話になりません。きちんとnginxの起動時にどの設定ファイルが読み込まれているのか確認しましょう。そのためには/etc/nginx/nginx.conf
を覗きみる必要があります。
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*; # <----- この記述がありますか?
# もしなければ追加してください
}
include /etc/nginx/sites-enabled/*
という記述があることで、/etc/nginx/sites-enabled
以下のファイルをすべて読み込むようにnginx.conf
に伝えることが出来ます。もしこれを書かないと、nginxはいつでもdafault.conf
しか読み込んではくれません(8敗)
Deploying static files
Before running nginx, you have to collect all Django static files in the static folder. First of all you have to edit mysite/settings.py adding:
# ~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
# ~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
and then run
uwsgi-tutorial/ $ python manage.py collectstatic
nginxを実行する前に、すべてのDjango静的ファイルをmysite/static
ディレクトリに収集する必要があります。そのためにはまずmysite/settings.py
を上記のように編集する必要があります。(訳者注:この一行によってDjangoがcollectstatic
するときにどこのディレクトリに集めればいいのか指定することが出来ます)
そうしたら、実際に静的ファイルをstatic
ディレクトリに集めましょう。python manage.py collectstatic
を実行してください。
Basic nginx test
Restart nginx:
sudo /etc/init.d/nginx restart
To check that media files are being served correctly, add an image called
media.png
to the/project/media
directory, then visit http://127.0.0.1:8000/media/media.png - if this works, you’ll know at least that nginx is serving files correctly.
メディアファイルが正しく配信されていることを確認するには、/project/media
ディレクトリにmedia.png
という画像ファイルを追加してみてください。(その後、このリンクにアクセスしてください)これが実際に表示されれば、少なくともnginxがファイルを正しく提供していることがわかります。
(訳者注:project
ディレクトリ(つまり一番外のmysite
ディレクトリ)の直下にmedia
ディレクトリを作成し、その中にmedia.png
というファイルを置いてみてください)
It is worth not just restarting nginx, but actually stopping and then starting it again, which will inform you if there is a problem, and where it is.
また、単にnginxを再起動するだけではなく、実際に停止してから再起動することで(訳者注:設定ファイルを再度読み込みなおさせることで)問題があるかどうか、またその問題がどこにあるのかを通知させることが出来ます。
$ sudo /etc/init.d/nginx stop
'''
[ ok ] Stopping nginx (via systemctl): nginx.service.
'''
$ sudo /etc/init.d/nginx restart
'''
[ ok ] Restarting nginx (via systemctl): nginx.service.
'''
$ sudo /etc/init.d/nginx reload
'''
[ ok ] Reloading nginx configuration (via systemctl): nginx.service.
'''
$ sudo /etc/init.d/nginx status
'''
$ sudo /etc/init.d/nginx status
● nginx.service - nginx - high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2018-04-01 15:42:52 JST; 32s ago
Docs: http://nginx.org/en/docs/
Process: 3120 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
Process: 3230 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 3196 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Process: 3191 ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 3198 (nginx)
Tasks: 2
Memory: 1.5M
CPU: 16ms
CGroup: /system.slice/nginx.service
tq3198 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
mq3232 nginx: worker process
Apr 01 15:42:52 94rs.work systemd[1]: Starting nginx - high performance web server...
Apr 01 15:42:52 94rs.work nginx[3191]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Apr 01 15:42:52 94rs.work nginx[3191]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Apr 01 15:42:52 94rs.work systemd[1]: Started nginx - high performance web server.
Apr 01 15:42:54 94rs.work systemd[1]: Reloading nginx - high performance web server.
Apr 01 15:42:54 94rs.work systemd[1]: Reloaded nginx - high performance web server.
'''
nginx and uWSGI and test.py
Let’s get nginx to speak to the “hello world”
test.py
application.
uwsgi-tutorial/ $ cd mysite
uwsgi-tutorial/mysite/ $ uwsgi --socket :8001 --wsgi-file test.py
This is nearly the same as before, except this time one of the options is different:
- socket :8001: use protocol uwsgi, port 8001
nginxに "hello world"のtest.pyアプリケーションと対話させてみましょう。上記のようにコマンドを入力するのですが、これはオプションのうちの1つが異なる場合を除いて、以前とほぼ同じです。socket :8001
というオプションは、HTTPではなく「uwsgiプロトコル」を用いて「8001番ポートを使う」ようにuWSGIに伝えています。
nginx meanwhile has been configured to communicate with uWSGI on that port, and with the outside world on port 8000. Visit: http://127.0.0.1:8000/
一方、nginxは、その**"8001"番ポート上でuWSGIと通信し**、"8000"番ポートで外部と通信するように設定されています。(訳者注:初心者にはかなりわかりづらいところだったので強調しておきます)
http://127.0.0.1:8000/
to check. And this is our stack:
the web client <-> the web server <-> the socket <-> uWSGI <-> Python
それでは現在の時点で何がどうなっているのか確認してみましょう。上記の構成が現時点での全体像です。
Meanwhile, you can try to have a look at the uswgi output at http://127.0.0.1:8001 - but quite probably, it won’t work because your browser speaks http, not uWSGI, though you should see output from uWSGI in your terminal.
一方であなたは、http://127.0.0.1:8001 にてuwsgiそれ自体の出力を見ようと試みることができますが、きっとうまく動作しないでしょう。おそらくはuWSGIからの出力が端末に表示されるだけです。なぜならあなたのブラウザはHTTP通信を行なえても、uWSGI通信のプロトコルには対応していないからです。
Using Unix sockets instead of ports
So far we have used a TCP port socket, because it’s simpler, but in fact it’s better to use Unix sockets than ports - there’s less overhead.
これまではTCPポートソケットを使用していました。これは簡単に通信が行えますが、実際にはポートよりもUnixソケットを使用するほうがオーバーヘッドが少なくて済みます。
Edit
mysite_nginx.conf
, changing it to match:
uwsgi-tutorial/mysite/ $ vi 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)
}
# ~~~~~~~~~~~~~~~~~~ 以下略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
上記のように、mysite_nginx.conf
を編集します(パスを訂正しコメントアウトを付け直すだけです!)
and restart nginx.
sudo /etc/init.d/nginx restart
Run uWSGI again:
This time the socket option tells uWSGI which file to use.
uwsgi-tutorial/ $ cd mysite
uwsgi-tutorial/mysite/ $ uwsgi --socket mysite.sock --wsgi-file test.py
nginxを再度起動し直し、TCPポートソケットではなくmysite.sock
を使ったUnixソケットでの通信を行うようにuWSGIに伝えましょう。
Try http://127.0.0.1:8000/ in the browser.
それでは、確認のためにこのリンクにアクセスしてみてください。
If that doesn’t work
Check your nginx error log(/var/log/nginx/error.log). If you see something like:
connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permission
denied)
then probably you need to manage the permissions on the socket so that nginx is allowed to use it.
もしうまくいかない場合、nginxのエラーログ /var/log/nginx/error.log
を確認してみてください。おそらくはnginxがmysite.sock
を使用できるように、ソケットのパーミッションを管理する必要があります。
Try:
# (very permissive)
uwsgi-tutorial/mysite/ $ uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
or:
# (more sensible)
uwsgi-tutorial/mysite/ $ uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664
上記のように、uwsgiコマンドの実行時にオプションとして --chmod-socket=666
または --chmod-socket=664
を付与することでパーミッションの問題は解決するでしょう。
You may also have to add your user to nginx’s group (which is probably www-data), or vice-versa, so that nginx can read and write to your socket properly.
あるいは、nginxがあなたのソケットを正しく読み書きできるように、あなたをnginxのグループ(おそらくwww-data
)に追加する必要があるかもしれません。そうすればnginxがあなたのソケットプロパティへの読み書きが可能になるでしょう。(訳者注:詳細なやり方は書かれていない)
It’s worth keeping the output of the nginx log running in a terminal window so you can easily refer to it while troubleshooting.
また、nginxログの出力を端末ウィンドウで実行しておくと、トラブルシューティング中に簡単に参照できるようになります。(訳者注:詳細なやり方は書かれていない)
Running the Django application with uwsgi and nginx
Let’s run our Django application:
uwsgi-tutorial/mysite/ $ uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664
Now uWSGI and nginx should be serving up not just a “Hello World” module, but your Django project.
それではいよいよDjangoアプリケーションをnginxとuWSGIを通してデプロイしてみましょう。上記のコマンドを実行してください。この時点で、uWSGIとnginxは test.py
による"Hello World"モジュールだけでなく mysite
というDjangoプロジェクトにも対応できているはずです。
さぁ、ページが表示されたでしょうか?
Configuring uWSGI to run with a .ini file
We can put the same options that we used with uWSGI into a file, and then ask uWSGI to run with that file. It makes it easier to manage configurations.
Create a file calledmysite_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
上記のように mysite_uwsgi.ini
(*.ini ; 起動ファイル)を利用することで、uWSGIで使用したのと同じオプションをファイルに入れて、そのファイルで実行するようにuWSGIに依頼することができます。 これにより、構成の管理が容易になります。(訳者注:つまり、いちいちコマンドラインからuWSGIにオプションでいろいろと指定する必要がなくなるということです)
And run uswgi using this file:
# the --ini option is used to specify a file
uwsgi-tutorial/mysite/ $ uwsgi --ini mysite_uwsgi.ini
Once again, test that the Django site works as expected.
実際に起動ファイルからuWSGIを使うときには、上記のようにコマンドを実行します。これにより、もう一度、Djangoサイトが期待通りに動作しているかをテストします。
補足事項
Install uWSGI system-wide
So far, uWSGI is only installed in our virtualenv; we’ll need it installed system-wide for deployment purposes.
Deactivate your virtualenv and install uWSGI system-wide:
$ deactivate
$ sudo pip install uwsgi
# Or install LTS (long term support).
# $ pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz
The uWSGI wiki describes several installation procedures. Before installing uWSGI system-wide, it’s worth considering which version to choose and the most appropriate way of installing it.
Check again that you can still run uWSGI just like you did before:
# the --ini option is used to specify a file
uwsgi-tutorial/mysite/ $ uwsgi --ini mysite_uwsgi.ini
Emperor mode
uWSGI can run in ‘emperor’ mode. In this mode it keeps an eye on a directory of uWSGI config files, and will spawn instances (‘vassals’) for each one it finds.
Whenever a config file is amended, the emperor will automatically restart the vassal.
# create a directory for the vassals
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# symlink from the default config directory to your config file
sudo ln -s /path/to/your/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/
# run the emperor
uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
You may need to run uWSGI with sudo:
sudo uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
The options mean:
- emperor: where to look for vassals (config files)
- uid: the user id of the process once it’s started
- gid: the group id of the process once it’s started
Check the site; it should be running.
Make uWSGI startup when the system boots
The last step is to make it all happen automatically at system startup time.
For many systems, the easiest (if not the best) way to do this is to use the
rc.local
file.
Edit/etc/rc.local
and add:
/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log
before the line “exit 0”.
And that should be it!
Further configuration
It is important to understand that this has been a tutorial, to get you started. You do need to read the nginx and uWSGI documentation, and study the options available before deployment in a production environment.
Both nginx and uWSGI benefit from friendly communities, who are able to offer invaluable advice about configuration and usage.
nginx
General configuration of nginx is not within the scope of this tutorial though you’ll probably want it to listen on port 80, not 8000, for a production website.
You should also configure a separate nginx location block for serving non-Django files. For example, it’s inefficient to serve static files via uWSGI. Instead, serve them directly from Nginx and completely bypass uWSGI.
uWSGI
uWSGI supports multiple ways to configure it. See uWSGI’s documentation and examples.
Some uWSGI options have been mentioned in this tutorial; others you ought to look at for a deployment in production include (listed here with example settings):
env = DJANGO_SETTINGS_MODULE=mysite.settings # set an environment variable
safe-pidfile = /tmp/project-master.pid # create a pidfile
harakiri = 20 # respawn processes taking more than 20 seconds
limit-as = 128 # limit the project to 128 MB
max-requests = 5000 # respawn processes after serving 5000 requests
daemonize = /var/log/uwsgi/yourproject.log # background the process & log
おわりに
結局の所、Qiitaやbeartailやstackoverflowとか見るより何より原典にあたるのが一番の近道だったりするようだ。そういう場所に残される記事はつまるところ個人の問題でしかなく、それがすべて個々人に対応できるかと言うとそうではない(より限定的な事象に関してはその優位性が勝るが)。普遍的に誰でも同じように利用できるように書かれているのが公式ドキュメントであるはずだし、困ったらググるより何より公式ドキュメントを読むことにします。(その結果得られたものは適宜フィードバックすればいいわけで)
拙い英語力(というか殆どはGoogle翻訳先生のおかげ)で和訳してみました。少しづつこういうことを続けていけば、おのずと自身の英語力も上がるはず……………と思いながらがんばります。