はじめに
mod_wsgi (+ Apache) を使ったFlaskアプリのデプロイは公式のドキュメントにも書かれているポピュラーな方法ですが、私が読んだ限りでは説明が初心者には不親切です.スクリプトが要所要所で端折られてるため,いまいち何をやったらいいのかわかりませんでした.
さらに私はFlaskアプリのパッケージ管理として Pipenv を使おうとしてたのですが、mod_wsgi, flask に Pipenv を組み合わせる方法となると英語で検索してもなかなかヒットしませんでした.
実際に丸一日くらい苦心してやってみたところ,上記の組み合わせでアプリをデプロイするにはやや複雑な手順が必要だったので、自分への備忘録も兼ねてここに記しておきたいと思います.
環境構成
- OS: Ubuntu 18.04
- Web Server: Apache 2.4
- Python: Python 3.6
デプロイへの道のり
1. Apache, mod_wsgi をインストール
$ sudo apt install apache2
$ sudo apt install libapache2-mod-wsgi-py3
Python 3 を使う場合は libapache2-mod-wsgi
ではなく libapache2-mod-wsgi-py3
を指定する必要があるみたいです.ここ結構なハマりポイントだと思います.
2. Apache の公開フォルダにFlaskアプリを追加する
/var/www/html
配下にFlaskアプリを追加します.今回は説明を簡単にするために Hello, World を表示するだけのプログラムにしましょう.
html 配下にwsgi-scripts
フォルダを作成してhello.py
という名前で以下のファイルを保存します.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello from flask!'
if __name__ == '__main__':
app.run()
書けたら
$ pipenv install
$ pipenv install flask
で仮想環境を作成しておきましょう.
3. wsgi ファイルを追加する
flaskアプリと同じフォルダにwsgiファイルも追加します.これが本番サーバーで稼働させるときに必要になるファイルです.なんかちょっと不思議な中身に見えますが,これがwsgiスクリプトというものらしいです.複雑に思えますが,最終行以外はmod-wsgiとpipenvを使うための準備です.
activate_this = '/home/hoge/.local/share/virtualenvs/wsgi-scripts-XXXXXX/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
import sys
sys.path.insert(0, 'var/www/html/wsgi-scripts')
from hello import app as application
ここで activate_this
に該当するパスは個々人の環境に合わせて修正する必要があります.要はvirtualenvのパスなのですが、確認方法としては pipenv shell
を起動したときに出てくるパスをコピーすればいいです.
4. conf ファイルを追加する
ここからは Apacheの設定です./etc/apache2/conf-available/
にwsgi.conf
を追加しましょう.
```/etc/apache2/conf-available/wsgi.conf`
WSGIDaemonProcess myapp
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias /myapp /var/www/html/wsgi-scripts/myapp.wsgi
Require all granted
純粋にwsgiを動かすだけなら WSGIScriptAlias だけ書けばいいのですが、Flaskアプリをうごかす場合は他の設定も書く必要があります.
書けたら以下のコマンドでサイトを有効化します.
$ sudo a2enconf wsgi
$ sudo sytemctl reload apache2
これで http://localhost/myapp にアクセスすれば,`hello from flask` が表示されるはずです.
## おまけ: Plotly Dash をデプロイする
Flaskアプリの一つであるPlotly Dashをデプロイする場合は少し変更が必要です
まずpyファイルを以下のように変更します.
```hello_dash.py
from flask import Flask
import dash
import dash_html_components as html
server = Flask(__name__)
@server.route('/')
def index():
return 'Hello Flask app'
app = dash.Dash(__name__, server=server, routes_pathname_prefix='/myapp/')
app.layout = html.Div('My Dash app')
if __name__ == '__main__':
app.run_server()
さらにwsgiファイルの最終行を以下のように変更します
from hello_dash import server as application
最後に confファイルも以下のように変更します
WSGIScriptAlias のパスを /
に変更するのがミソです。これをしないとJSでエラーが出てしまいます。
WSGIDaemonProcess myapp
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/html/wsgi-scripts/myapp.wsgi
WSGIPassAuthorization On
<Directory /var/www/html/wsgi-scripts>
Require all granted
</Directory>
WSGIPassAuthorization
は dash_auth
を使う際に必要です
これでDashアプリが動きます。