Program, WordPress
Python Flaskアプリを nginx + uWSGI 環境下へデプロイしたのでメモ
こんばんは、ころすけ(@wg_koro)です。
先日、Google Reader終了カウントダウンページを作りました。この時に使ったのがPython+Flask。
ローカルで作って、さあサーバーへデプロイしよう・・・という時にふと気づいた。
「今更mod_pythonはないなぁ。せっかくだからuWSGIにしよう!」
というわけで、今回、カウントダウンページはFlask + nginx + uWSGIで構築しました。この構築時のメモをつらっと書き記します。
uWSGI
超簡単。
$ pip install uwsgi
以上w!
インストールはさくっとできたので、動かしてみる。ドキュメントを参考に、簡単なFlaskアプリを書いて試す。
1 2 3 4 5 6 7 8 9 |
#!/usr/bin/env python # examle.py from flask import Flask app = Flask(__name__) @app.route('/') def index(): return "<span style='color:red'>I am app 1</span>" |
Flaskは起動ファイルがそのままWSGIファイルとして使えるので、ダイレクトに指定する。
$ uwsgi --http :9090 --wsgi-file /var/www/example.py
これで動く。確認するにはブラウザで9090ポートへアクセスするか、サーバー内から http://localhost:9090/ へwgetする。正常に動作していれば、HTMlが返ってくる。
次に、作ったFlaskアプリケーションを動かしてみる。Flaskはvirtualenv環境下で作ったので、uwsgi起動時にvirtualenv下のディレクトリパスを指定しないとダメ。
参考:uWSGI+virtualenv+Flask | おいぬま日報
$ uwsgi -s /tmp/mysock.sock --http :9090 -H /home/myaccount/.virtualenvs/bye --python-path /var/www/myapp -w app:app --processes 3 --threads 2
これでOK。
ミソは下記の通り。
- -H: virtualenv下のディレクトリパスを指定
- –python-path: Flaskアプリを設置しているディレクトリ
- -w: Flaskオブジェクトを代入した変数名・・・であってるのかな? app = Flask(__name__) ←コレ
毎回、このオプションを指定するのはしんどいので、設定ファイル(uwsgi.ini)にしてしまう。
[uwsgi] socket = /tmp/mysock.sock http = :9090 venv = /home/smaster/.virtualenvs/bye python-path = /var/www/deploy/current/source wsgi = app:app processes = 3 threads = 2
起動時はこの設定ファイルを呼び出すだけでOK!
$ uwsgi uwsgi.ini
次に、uwsgiがサーバー再起動時に自動で走るように、サービス起動スクリプトを作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
#!/bin/bash # # bye-reader start script # # chkconfig: 345 99 1 # description: uwsgi start script # processname: uwsgi # pidfile: /tmp/uwsgi.pid # # Source function library. . /etc/init.d/functions PROGNAME="uwsgi" PID="/tmp/$PROGNAME.pid" LOCK="/tmp/$PROGNAME.lock" RETVAL=0 UWSGI_HOME="/home/myaccount/.virtualenvs/venvdir" UWSGI_BIN="$UWSGI_HOME/bin/uwsgi" UWSGI_APP_DIR="/var/www/" UWSGI_APP_BIN="$UWSGI_APP_DIR/deploy/current/source" UWSGI_LOG="/var/log/uwsgi/$PROGNAME.log" UWSGI_APP_INIT="$UWSGI_APP_DIR/uwsgi.ini" PROG=$UWSGI_BIN [ -f $PROG ] || exit 0 start() { echo -n "Starting $PROGNAME: " daemon $PROG $UWSGI_APP_INIT --uid nginx --gid nginx -d $UWSGI_LOG --master --pidfile $PID echo [ $RETVAL = 0 ] && touch $LOCK return $RETVAL } stop() { echo -n "Stopping $PROGNAME: " killproc -p $PID $PROGNAME -INT RETVAL=$? echo [ $RETVAL = 0 ] && rm -f $LOCK $PID } show_status() { status $PROGNAME } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) show_status ;; *) echo "Usage: $PROGNAME {start|stop|restart|status}" RETVAL=2 ;; esac exit $RETVAL |
/etc/init.d/uwsgi として設置し、パーミッションを変更。
こうすると service uwsgi start/stop/restart で動かすことが可能。
ついでに
sudo chkconfig –add uwsgi
sudo chkconfig uwsgi on
として、自動起動するようにする。
nginx
nginxの設定ファイルは結構シンプル。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
server { listen 80; server_name goodbyereader.wingall.com; access_log /var/log/nginx/bye.access_log.log main; error_log /var/log/nginx/bye.error_log.log; location ~ /static/.*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) { root /var/www/deploy/current/source/; index index.html; log_not_found on; expires 30d; break; } location / { proxy_cache czone; proxy_cache_valid 200 1m; proxy_cache_valid 404 5m; include uwsgi_params; uwsgi_pass unix:/tmp/mysock.sock; } } |
静的ファイルだけnginxで受けて、残りはuwsgiへ流す。これでできあがり!
意外と楽に組み込むことができました。迷った箇所はあまり無い感じ。uwsgiは結構シンプルなので、PythonでWebアプリ書く時はこれで決まりかな〜。
コメントを残す