Flaskで作成したアプリケーションをサブディレクトリにマウントして公開する方法。
Flaskの機能ではないのでドキュメントを見ていてもなかなか見つけにくいが、WSGIミドルウェアを使用するものが正解。
毎回調べている気がするのでメモしておく。
設定内容
以下のように、http://localhost/console
で公開する。
# nginx config
upstream console {
server 127.0.0.1:8110;
}
server {
...
location /console {
proxy_pass http://console;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...
}
このままではurl_for
等のurl生成が壊れるので、
APPLICATION_ROOT
を設定してやり、WSGIのミドルウェアを挟んでやるとうまく動作する。
環境変数を参照するようにすると、開発環境等にもコード修正なしで対応できる。
# app.py
import os
from flask import Flask, request, url_for, render_template
from werkzeug.serving import run_simple
from werkzeug.middleware.dispatcher import DispatcherMiddleware
application = Flask(__name__)
application_root = os.environ.get('FLASK_APPLICATION_ROOT', '')
application.config['APPLICATION_ROOT'] = application_root
application.wsgi_app = DispatcherMiddleware(run_simple, {application_root: application.wsgi_app})
@application.route('/')
def index():
urls = (
url_for('index', _external=True),
url_for('index'),
url_for('static', filename='css/style.css'))
return '<br>'.join(urls)
if __name__ == "__main__":
application.run(host=0.0.0.0)
今回は、WSGIコンテナにNGINX
Unitを使用してみた。 インストール方法は割愛。
# config.json
{
"listeners": {
"*:8110": {
"pass": "applications/console"
}
},
"applications": {
"console": {
"type": "python",
"user": "yamori",
"group": "yamori",
"working_directory": "/home/yamori/workspace/console/",
"path": "/home/yamori/workspace/console/",
"home": "/home/yamori/.anyenv/envs/pyenv/versions/console",
"module": "app",
"environment": {
"FLASK_APPLICATION_ROOT": "/console"
}
}
}
}
ソケットにput
して反映させる。
$ sudo curl -X PUT --data-binary @config.json --unix-socket /run/control.unit.sock http://localhost/config/
以上で、webサーバー経由でのアクセスhttp://localhost/console
、pythonファイルの直接実行時のhttp://localhost:5000
どちらの場合でも正しいパスが生成される。