Edited at

Flask + uWSGI + Nginx でハローワールドするまで @ さくらのVPS (CentOS 6.6)

More than 1 year has passed since last update.


前提

Flaskアプリケーションのローカル環境での開発方法は知っていて、本番環境でのdeploymentの方法が知りたい。uWSGIやNginxについてはあまり知らない。


概略

Flaskの公式によると


You can use the builtin server during development, but you should use a full deployment option for production applications.


とのことなので、アプリを公開するには組み込みサーバーの利用はせずに、別の方法を考える必要があるらしい。様々な方法があるようだが、ここではuWSGIとNginxという組合せで進める。

まず、基本的な言葉の整理からおこなう。


uWSGI

uWSGIは、WSGIと名前は似ているが異なる概念であることに注意する。

WSGI(Web Server Gateway Interface)はPEP333において


a simple and universal interface between web servers and web applications or frameworks


と定義される仕様のことであり、ウェブサーバとアプリケーションをつなぐインターフェースの役割を担う。これにより、フレームワークとサーバの実装が一般化され、アプリケーションの移植可能性が高まるなどのメリットがある。

uWSGIは、WSGIアプリケーションとウェブサーバをつなぐサーバを指す。uWSGIは、uWSGI、HTTP、そしてFastCGIなどのプロトコルを用いてウェブサーバと通信する。ここではuwsgiというサーバを利用して、uWSGIプロトコルによりウェブサーバと通信する(言葉が紛らわしいですが、uWSGIは文脈によってサーバを指したりプロトコルを指したりするので注意が必要です)。

以上の関係を図式的に表すと次のようになる。

Framework <-> uWSGI <-> Web Server <-> Client

今回の場合では

Flask <-> uwsgi <-(uWSGI protocol)-> Nginx <-(HTTP)-> Client

となる。


インストール

flaskとuwsgiをpipで入れておく。ここは情報が豊富なので省略。


デモアプリの作成


アプリの構成

myapp

|-app.py
|-myapp.ini
|-venv


app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"

if __name__ == "__main__":
app.run()


myapp.ini

これについては後述する。

[uwsgi]

module = app
callable = app
master = true
processes = 1
socket = /tmp/uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true


Nginxの設定

Nginxの設定ファイルは、大本の設定ファイルは/etc/nginx/nginx.confであり、このファイルの中にinclude /etc/nginx/conf.d/*.confと記述してあることで、さらに下位の/etc/nginx/conf.d/内にある*.confファイルが呼び出される仕組みとなっている。ここでは、アプリケーションを動かすのに必要な最小限の設定ファイルをconf.d/内に置くこととする。

server {

listen 80;

location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
}

これは、サーバのルートにHTTP(ポート80)でアクセスがあれば、/tmp/uwsgi.sockというソケットに接続するという設定になっている。上述したように、NginxはuWSGIに接続するのだが、ここではUNIXソケットを間に噛ませて通信する。これにより、ポート番号を消費せずに済む。

このことを加味した全体の接続イメージは次のようになる。

Flask <-> uwsgi <-> socket <-> Nginx <-> Client


uWSGIの設定

ここまででapp.pyを任意の場所に設置してNginxの設定を済ませていれば、次のコマンドで一応アクセスすることができる。

$ uwsgi --socket /tmp/uwsgi.sock --module app --callable app --chmod-socket=666

あるいは

$ uwsgi -s /tmp/uwsgi.sock --w app:app --chmod-socket=666

ブラウザからウェブサーバのIPアドレスにアクセスすると、ハローワールドが表示されるはず。上のコマンドの各オプションは次のような意味をもつ。

-s|--socket   接続先のソケットの指定

--module モジュールの指定
--callable WSGIにて規定されるcallableオブジェクトの指定
--chmod-socket ソケットのアクセス権の変更

しかし、上のオプションを毎度打ち込むのも大変なので、uwsgiのための設定ファイルを作成する。それが上述したmyapp.iniとなる。設定ファイルを作成していれば、次のコマンドで同様にuWSGIサーバーが立ち上がる。

$ uwsgi --ini myapp.ini


おわりに

ここまでで、一応FlaskアプリケーションをNginx経由で動かすことはできた。あとは、起動時に自動実行されるよう設定するなどすればOKだろう(そのためには/etc/rc.localをいじればいい)。


参照