Ubuntu 16.04 で Systemd + Nginx + uWSGI + Flask が動くようにやっていく。
[2018/04 追記] Ubuntu 18.04 と Flask 1.0 がリリースされたので動かしてみたところ、同じやり方で普通に動かせた。
Setup
とりあえずやるやつ。
# apt update
# apt upgrade
Python 3 + pip を入れる
Ubuntu 16.04 だと Python 3.5 は既に入っているが、pip が入っていないので入れる。
# apt install python3-pip
Flask を使うので入れておく。
# pip3 install flask
アプリケーションを設置
場所はどこでも良いけど今回は ~/app
に置くことにする。
アプリケーションの本体はこんな感じ。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
if __name__ == "__main__":
app.run()
これだけでも $ python3 hello.py
でサーバを起動できるはず。
uWSGI
apt
でも入れれるけど、要らん init スクリプトが入ったりちょっとバージョンが古かったりするので pip
で入れたほうが良い。
# pip3 install uwsgi
[uwsgi]
socket = /tmp/uwsgi.sock
chmod-socket = 666
chdir = %d
module = hello:app
master = 1
processes = 4
HTTP ではなく Unix ドメインソケットを作るようにしている。
Nginx から触れる用に chmod-socket = 666
も設定する。
%d
は「この設定ファイルがあるディレクトリパス」を表す特殊な変数1で、これにより Systemd から起動したときでも「設定ファイルのあるディレクトリに移動 (chdir) して、モジュール hello
から app
を読み込んで起動する」という設定になる。
uWSGI の設定ファイル内にアプリケーションのディレクトリパスを記述する必要がなくなるので便利。
processes = 4
を指定して 4 プロセス起動するようにしているが、このあたりは CPU のコア数などに応じて変える。
Systemd
続いては Systemd で uWSGI プロセスを管理できるようにする。
uWSGI 公式の Systemd 対応ドキュメントはなぜか Emperor を使う設定しか書いてないけど、単一アプリを動かすだけなら別に Emperor を使わなくてもいい。
[Unit]
Description = uwsgi
[Service]
Restart = always
ExecStart = /usr/local/bin/uwsgi --ini=/home/ubuntu/app/uwsgi.ini
ExecReload = /bin/kill -s HUP ${MAINPID}
KillSignal = QUIT
[Install]
WantedBy = multi-user.target
- uWSGI は SIGTERM を送ると reload するので、サービスを止めるときは SIGQUIT を送るように明示的に設定しておく必要がある
-
ExecReload
で SIGHUP を送るようにしておくと Graceful Restart できるので便利
詳しくは: Managing the uWSGI server — uWSGI 2.0 documentation
uWSGI の自動起動設定をする。
# systemctl enable uwsgi
Nginx
Nginx で HTTP リクエストを受け取って uWSGI プロセスに流すように設定する。
# apt install nginx
デフォルトの設定は削除して、以下の設定ファイルを追加する。
# rm /etc/nginx/sites-enabled/default
server {
listen 80 default_server;
server_name _;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
}
既に ngx_http_uwsgi_module
というモジュールが入っていて、uwsgi_pass
というディレクティブで Unix ドメインソケットに流すことができる。
Nginx の自動起動設定をしておく。
# systemctl enable nginx
サービス起動
# systemctl start uwsgi
# systemctl start nginx
ブラウザからサーバにアクセスすれば Hello World!
と表示されるはず。