Edited at

Python + uWSGI + nginx


概要

CentOS 6/7で、Python + uWSGI + nginxの組み合わせでFlaskアプリを動かすまでの試行錯誤。


関係パッケージインストール

yum install -y https://centos6.iuscommunity.org/ius-release.rpm

yum install -y python36u python36u-devel python36u-libs python36u-pip

pip3.6 install uwsgi
pip3.6 install flask


アプリ設定

/var/www/アプリディレクトリ/uwsgi.ini

[uwsgi]

#application's base folder
chdir = /var/www/アプリディレクトリ

#python module to import
app = app
module = %(app)

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

plugin = python36

#socket file's location
socket = /var/run/uwsgi/%n.sock

#permissions for the socket file
chmod-socket = 644

#location of log files
logto = /var/log/uwsgi/%n.log

master = true

# maximum number of worker processes
processes = 100

# clear environment on exit
vacuum = true

/var/www/アプリディレクトリ/app.py

from flask import Flask

app = Flask(__name__)

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

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


uWSGI起動

いちいち手動で立ち上げなくていいよう、起動スクリプトに登録する。

また、複数立ち上げられるよう、Emperorとかいう仕組みを利用する。

mkdir -p /var/{run,log}/uwsgi

chown -R nginx:nginx /var/{run,log}/uwsgi
mkdir -p /etc/uwsgi/vassals
ln -sf /var/www/アプリディレクトリ/uwsgi.ini /etc/uwsgi/vassals/アプリディレクトリ.ini

※/etc/uwsgi/vassals配下に各アプリのiniファイルへのシンボリックリンクを張る

※nginx:nginxの部分は起動ユーザーに応じて書き換える


[CentOS 7の場合] /etc/systemd/system/uwsgi.service の作成

[Unit]

Description=uWSGI Emperor
After=syslog.target

[Service]
ExecStartPre=-/bin/mkdir -p /var/log/uwsgi
ExecStartPre=-/bin/chown -R nginx:nginx /var/log/uwsgi
ExecStartPre=-/bin/mkdir -p /var/run/uwsgi
ExecStartPre=-/bin/chown -R nginx:nginx /var/run/uwsgi
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/emperor.ini
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

systemctl enable uwsgi.service

systemctl start uwsgi.service


[CentOS 6の場合] /etc/init.d/uwsgi の作成

https://zafiel.wingall.com/archives/7513 から拝借し、起動コマンドは以下の様に書き換えた。

daemon $PROG --master --emperor /etc/uwsgi/vassals --die-on-term --uid nginx --gid nginx -d $UWSGI_LOG --pidfile $PID

chmod 755 /etc/init.d/uwsgi

service uwsgi start
chkconfig uwsgi on


nginxと連携

TLS証明書を事前に作っておく。

upstream backend {

server 127.0.0.1:8080;
keepalive 128;
}

server {
listen 80;
server_name ドメイン名;

location / {
rewrite ^.*$ https://ドメイン名$request_uri last;
}
}

server {
listen 443;
server_name ドメイン名;

#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;

ssl on;
ssl_certificate /etc/pki/tls/certs/ドメイン名.crt;
ssl_certificate_key /etc/pki/tls/private/ドメイン名.nopass.key;
ssl_protocols TLSv1;
ssl_ciphers HIGH:!ADH:!MD5:!DES:!3DES;

location / {
set $do_not_cache 1;

proxy_pass http://backend;
proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;
proxy_cache zone1;
proxy_cache_key $scheme://$proxy_host$uri$is_args$args;
proxy_cache_valid 200 10m;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

server {
listen 8080;
server_name ドメイン名;
root /var/www/アプリディレクトリ/public;

access_log /var/log/nginx/access_8080.log main;

location / {
try_files $uri @rewrite;
}
location @rewrite {
include uwsgi_params;
uwsgi_pass unix:///var/run/uwsgi/アプリディレクトリ.sock;
uwsgi_connect_timeout 600s;
uwsgi_read_timeout 600s;

uwsgi_param SERVER_ENV development;
}
}

service nginx restart


動作確認

https://ドメイン名/

Hello World! と表示された。