前提
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
をいじればいい)。
参照
- Web Server Gateway Interface - Wikipedia
- PEP 0333 -- Python Web Server Gateway Interface v1.0 | Python.org
- uWSGI — Flask Documentation (0.10)
- How To Serve Flask Applications with uWSGI and Nginx on Ubuntu 14.04 | DigitalOcean
- How To Deploy Flask Web Applications Using uWSGI Behind Nginx on CentOS 6.4 | DigitalOcean
- Set up Django, nginx and uwsgi