この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Flaskの組み込みWebサーバーを使ったインストールは過去にご紹介しました。
EC2上でFlaskを動かしてみる | Developers.IO
プロダクション環境では組み込みWebサーバーでの運用はお勧めできないため、 今回は mod_wsgi モジュールを使って Apache 上で Flask アプリケーションを動かします。
システム構成図
コンポーネントについて
- Apache : ウェブサーバー
- Flask :Web Server Gateway Interface(WSGI) アプリケーション
- mod_wsgi : WSGI インターフェースのPythonアプリケーションを Apache 上で動作させるApacheモジュール
- virtualenv : システムワイドではない専用のPython環境を提供
検証環境
- Amazon Linux/2015.09
- Apache/2.4.16 (Amazon)
- mod_wsgi/3.5
- Python/2.7.10
- Flask/0.10.1
作業の流れ
Apache/mod_wsgiのインストール
Apache httpd 2.4 と Python2.7 向けの mod_wsgi をインストールします。
$ sudo yum install -y mod24_wsgi-python27
- apr
- apr-util
- httpd24
- httpd24-tools
- mod24_wsgi-python27
がまとめてインストールされます。
Apache(2.4)やPython(2.7)のバージョンは適宜読み替えてください。
Apacheの自動起動を有効にし、起動します。
$ sudo chkconfig httpd on
$ sudo service httpd start
Flaskアプリケーションのインストール
/var/www/flask_wsgi_demo
以下にアプリケーションをインストールします。
最終的に/var/www/flask_wsgi_demo
以下のファイル構成は次の様になります。
$ tree -L 2
.
|-- app.py # Flask application
|-- flask_wsgi_demo.wsgi # WSGI interface file
|-- requirements.txt # package requirements file
`-- venv # virtual environment
|-- bin
|-- include
|-- lib
|-- lib64
|-- local
`-- pip-selfcheck.json
ディレクトリを用意
root ユーザーで作業します。
# mkdir /var/www/flask_wsgi_demo
# cd /var/www/flask_wsgi_demo
# virtualenv venv
New python executable in venv/bin/python2.7
Also creating executable in venv/bin/py
# . venv/bin/activate
(venv)$
Python パッケージをインストール
Flask(0.10.1) をpipでインストールします。 依存パッケージは requirements.txt で指定します。
# cat requirements.txt
Flask==0.10.1
# pip install -r requirements.txt
アプリをインストール
ルートパスにアクセスすると、"Hello World!" を返すだけの Flask アプリを用意します。
# app.py
# "hello world" flask app
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
組み込みWebサーバーでFlaskアプリを起動
Flaskの組み込みWebサーバーでFlaskアプリを起動します。
$ python app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [13/Mar/2016:04:41:07 +0000] "GET / HTTP/1.1" 200 12 "-" "curl/7.40.0"
別ターミナルから、ローカルホストの 5000 に GET して正常なレスポンスが帰ることを確認します。
$ curl -D - localhost:5000
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 12
Server: Werkzeug/0.11.4 Python/2.7.10
Date: Sun, 13 Mar 2016 04:42:23 GMT
Hello World!
"Hello World!" と返ってきたのでOKです。 レスポンスヘッダーから組み込みサーバーは「Werkzeug/0.11.4」で動いていることがわかります。
Apache/mod_wsgi でFlaskアプリを起動
次に mod_wsgi モジュール経由で Apache でFlaskアプリを起動します。
.wsgi ファイルを作成
mod_wsgi がアプリ起動時に利用する .wsgi ファイルを作成します。 中身は Python プログラムです。
# flask_wsgi_demo.wsgi
import os
import sys
DIR=os.path.dirname(__file__)
sys.path.append(DIR)
activate_this = os.path.join(DIR, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
from app import app as application
次の箇所でFlaskアプリケーションのあるパスをサーチパスに追加します。
DIR=os.path.dirname(__file__)
sys.path.append(DIR)
次の箇所でvirtualenvを読みこむようにします。
activate_this = os.path.join(DIR, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
deactivate
コマンドを実行して、virtualenv 環境から一時的に抜け、正しく設定できているか確認します
# deactivate # <- disabple virtualenb
# python flask_wsgi_demo.wsgi
# echo $?
0
例えば .wsgi ファイル内でvirtualenb を正しく読み込めていなければ、以下のような Flask モジュールのインポートエラーが発生します。
# python flask_wsgi_demo.wsgi
Traceback (most recent call last):
File "flask_wsgi_demo.wsgi", line 7, in <module>
from app import app as application
File "/var/www/flask_wsgi_demo/app.py", line 1, in <module>
from flask import Flask
ImportError: No module named flask
Apache 設定の変更
最後の Apache の設定変更をします。
次の内容のファイル /etc/httpd/conf.d/flask.conf
を追加します。
<VirtualHost *:80>
ServerName example.com
WSGIDaemonProcess flask_wsgi_demo user=apache group=apache threads=5
WSGIScriptAlias / /var/www/flask_wsgi_demo/flask_wsgi_demo.wsgi
WSGIScriptReloading On
<Directory /var/www/flask_wsgi_demo>
WSGIProcessGroup flask_wsgi_demo
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
主要なディレクティブについてだけ解説します。
WSGIScriptAlias
.wsgi ファイルのパスです。
WSGIScriptReloading
この設定を On にしておくと、.wsgi ファイルの変更イベントを捕まえせて、Apacheのデーモンプロセスが設定を再読み込します。
Directory
Flask アプリケーションのパス
Apache 設定を確認し、Apacheを再起動します。
# service httpd configtest
Syntax OK
# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
Apache が LISTEN している 80 番ポートにローあるホストとインターネットから HTTP GET して、動作を確認します。
$ curl -D - localhost
HTTP/1.1 200 OK
Date: Sun, 13 Mar 2016 04:41:07 GMT
Server: Apache/2.4.16 (Amazon) mod_wsgi/3.5 Python/2.7.10
Content-Length: 12
Content-Type: text/html; charset=utf-8
Hello World!
$ curl ec2-52-192-162-44.ap-northeast-1.compute.amazonaws.com
Hello World!
レスポンスヘッダーからサーバーは Apache/mod_wsgi であることがわかります。
まとめ
今回は Python 製マイクロフレームワークとApache/mod_wsgi の連携を紹介しました。
WSGI のおかげで gunicornやuWSGI(nginx) など他のウェブサーバーとも容易に連携させることもできます。
他の連携方法についても、機会があれば紹介したいと思います。