Edited at

ちゃんと運用するときのuWSGI設定メモ

某アプリのバックエンドをFlask+uWSGI+Nginxでつくったのでやったことまとめました。


Nginxとの連携


wsgiプロトコルで繋げる方法


nginx.conf

location / {

include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}


uwsgi.ini

socket=127.0.0.1:3031


ちなみにこの設定だと、uWSGIだけデバッグデバッグーとか言って http://127.0.0.1:3031 をブラウザで叩いても何も見えないです。uwsgiのオプションのsockethttpの違いを知らずに数分ハマった。


httpプロキシとして繋げる方法


nginx.conf

location / {

include uwsgi_params;
proxy_pass http://127.0.0.1:3031;
}


uwsgi.ini

http=127.0.0.1:3031


直感的なプロキシ。最初これしか方法ないと思ってた。これは http://127.0.0.1:3031 で見えるやつです。


sokectで繋げる方法(採用)

アプリ複数公開するとき余計なポート番号消費しないので基本これでいいと思う。これ採用。


nginx.conf

location / {

include uwsgi_params;
uwsgi_pass unix:/path/to/app/app.sock
}


uwsgi.ini

socket=/path/to/app/app.sock



uWSGI Emperor

複数アプリをuWSGIで管理するとき便利なので使う。

参考:http://qiita.com/5t111111/items/e170fead91261621b054#1-8

自動起動も楽になった!


細かいチューニングパラメタ

processes とか limit-as とか max-requests とか harakiri とか。harakiriて。

参考:http://docs.djangoproject.jp/en/latest/howto/deployment/wsgi/uwsgi.html

DjangoのサイトだけどwsgiアプリならFlaskとかでも参考になる。

ちなみにdaemonizemaster はEmperorを使ってるのでONにしてない。多分そういうことだと思うけど違ったらすいません。ツッコミ待ちです。

負荷試験とかやりながら設定いじる。


デプロイ時uWSGIリロード

ファイル変更しても反映されないので、


uwsgi.ini

touch-reload=/path/to/app/reload.trigger


とかにして、デプロイ時に /path/to/app/reload.trigger をtouchしてやると、次回リクエスト受付時にuWSGIがリロードする。

デプロイのスクリプトにtouchを仕込んでおくことにした。

参考:http://field-notes.hatenablog.jp/entry/2012/05/09/115600

(別解)

ファイルを監視する。

参考:http://d.hatena.ne.jp/dayflower/20121017/1350447805


ログローテートでログファイルを見失わない

リリース後にギャーってなるやつ。


uwsgi.ini

touch-logreopen=/path/to/app/logreopen.trigger


とかにして、

/path/to/uwsgi.log {

daily
rotate 7
missingok
notifempty
compress
sharedscripts
size 1M
postrotate
touch /path/to/app/logreopen.trigger
endscript
}

参考:http://taichino.com/memo/3843


(追記)結局こんな感じにしてますっての書いとくね


/etc/nginx/conf.d/sample_nginx.conf


sample_nginx.conf

# IPで叩かれたとき嫌だから。なくてもいい

server {
listen 80 default_server;
server_name _;
root /var/app/dummy;
index index.html;
}

server {
listen 80;
server_name sample.com;
charset utf-8;
client_max_body_size 75M;

location / { try_files $uri @uwsgi; }
# static はNginxに任せよう
location /static/ {
root /var/app/sample/webapp;
}
location @uwsgi {
include uwsgi_params;
uwsgi_pass unix:/var/app/sample/sample_uwsgi.sock;
}
}



/etc/uwsgi/vassals/sample_uwsgi.ini

uWSGI Emperorのためにuwsgi.iniを /etc/uwsgi/vassals/ にまとめとく。


sample_uwsgi.ini

[uwsgi]

base = /var/app/sample

app = main # Flask開始するのがmain.py だったら main
# Djangoの場合は sample.wsgi:application みたいな感じ

module = %(app)

# このアプリを動かすvirtualenv へのパス
# 生Pythonつかってる場合はPythonのディレクトリへのパスかな?
home = /home/www-data/venvs/sampleapp

pythonpath = %(base)

socket = %(base)/%n.sock

chmod-socket = 666

#the variable that holds a flask application inside the module imported at line #6
callable = app

# ロギング
logto = /var/log/uwsgi/%n.log
# logrotate の postrotate に仕込むやつ
touch-logreopen = %(base)/.logreopen_trigger

# uwsgi をリロードするトリガ
touch-reload = %(base)/.uwsgi_touch

max-requests = 1000
harakiri = 60

# emperorから使うからコメントアウトしてみた
#master=True
#daemonize=/var/log/uwsgi/sample.log



/etc/init/uwsgi.conf (uWSGI Emperor起動用) (CentOS6用)


uwsgi.conf

description "uWSGI"

start on runlevel [2345]
stop on runlevel [06]
respawn

# uwsgi emperor 用に uwsgi だけインストールした uwsgi という名前のvirtualenv 切ってます。ぼくは。
# そうでない場合は、uwsgi のインストール先を指定すればうごく筈
env UWSGI=/home/www-data/venvs/uwsgi/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log

# uid と gid は適宜変える
exec $UWSGI --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto $LOGTO


start uwsgi

で/etc/uwsgi/vassals 以下のuwsgiアプリ全部起動。

自動起動も適宜やる


/etc/systemd/system/uwsgi.service (uWSGI Emperor起動用) (CentOS7用)


uwsgi.service

[Unit]

Description=uWSGI
After=syslog.target

[Service]
# uwsgi emperor 用に uwsgi だけインストールした uwsgi という名前のvirtualenv 切ってます。ぼくは。
# そうでない場合は、uwsgi のインストール先を指定すればうごく筈
# あと uid と gid は適宜変える
ExecStart=/home/www-data/venvs/uwsgi/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto /var/log/uwsgi/emperor.log
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target


systemctl start uwsgi

で/etc/uwsgi/vassals 以下のuwsgiアプリ全部起動。

自動起動は適宜。