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

  • 90
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

前提

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をいじればいい)。

参照