93
106

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Django + uWSGI + nginx (uWSGIチュートリアルの和訳)

Last updated at Posted at 2018-03-29

はじめに

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が使われているので適宜読み替えてください)

terminal
$ 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をご利用の場合、localhost127.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

terminal
# $ 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:

terminal
uwsgi-tutorial/mysite/ $ vi test.py # copy & paste contents below to this file
test.py
# 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:

terminal
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:

terminal
uwsgi-tutorial/mysite/ $ uwsgi --http :8000 --module mysite.wsgi

Djangoの実行サーバーが動いていることが確認できたら、今度はmysiteプロジェクトをuWSGIに動かさせてみましょう。上記コマンドを実行してください。

http://127.0.0.1:8000

  • 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

terminal
# (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)が連携できていることを意味します。
confirm_starting_nginx.PNG

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 the nginx 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をつくってください)

terminal
$ 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_params

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 … )

terminal
$ 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

※単なるコピペで済ます前に、設定ファイルに書かれた相対パス / 絶対パスの指定をご自身のものに変更してください。

sites-available/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を覗きみる必要があります。

/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:

mysite/settings.py
# ~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

# ~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

and then run

terminal
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:

terminal
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を再起動するだけではなく、実際に停止してから再起動することで(訳者注:設定ファイルを再度読み込みなおさせることで)問題があるかどうか、またその問題がどこにあるのかを通知させることが出来ます。

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.
'''
nginxの設定ファイル再読込とステータス管理
$ 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.

terminal
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:

terminal
uwsgi-tutorial/mysite/ $ vi 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)
}
# ~~~~~~~~~~~~~~~~~~ 以下略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

上記のように、mysite_nginx.confを編集します(パスを訂正しコメントアウトを付け直すだけです!)

and restart nginx.

terminal
sudo /etc/init.d/nginx restart

Run uWSGI again:
This time the socket option tells uWSGI which file to use.

terminal
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:

/var/log/nginx/error.log
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:

terminal
 # (very permissive)
uwsgi-tutorial/mysite/ $ uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666

or:

terminal
 # (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:

terminal
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プロジェクトにも対応できているはずです。

http://127.0.0.1:8000/

さぁ、ページが表示されたでしょうか?

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 called mysite_uwsgi.ini:

uwsgi-tutorial/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

上記のように mysite_uwsgi.ini (*.ini ; 起動ファイル)を利用することで、uWSGIで使用したのと同じオプションをファイルに入れて、そのファイルで実行するようにuWSGIに依頼することができます。 これにより、構成の管理が容易になります。(訳者注:つまり、いちいちコマンドラインからuWSGIにオプションでいろいろと指定する必要がなくなるということです)

And run uswgi using this file:

terminal
 # 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:

terminal
$ 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:

terminal
 # 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.

terminal
# 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:

terminal
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:

rc.local
/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翻訳先生のおかげ)で和訳してみました。少しづつこういうことを続けていけば、おのずと自身の英語力も上がるはず……………と思いながらがんばります。

参考文献

93
106
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
93
106

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?