Flask+Pipenv+Gunicorn+Apacheでwebサーバーを構築する
概要
開発時は、Flaskのbuild in サーバーで事足りましたが、いざ本番環境にdeployするときには、WARNING: This is a development server. Do not use it in a production deployment.
とあるように、build in サーバーは使わない方がいいので、python系のフレームワークを本番環境で使うときにはどうしたらいいのかをまとめます。
もともとinstallされているpythonを使うと依存関係でごちゃごちゃするので、pyenvでinstallしたpythonおよびpipでpipenvをinstallし、そのpipenvを使って、パッケージを管理すると比較的わかりやすいです。
- pipenvをinstallするためのpackageをinstallする
- pyenvをinstallする
- pyenvで好みのversionのpythonをinstallする
参考:
pyenvを用いたpython環境構築手順(CentOS7.1)
- globalで利用するpipでpipenvをinstallする
- pipenvでpackageを管理する(今回の場合は、flaskやgunicornなど)
開発環境
- CentOS Linux release 8.1.1911
- pipenv, version 2018.11.26
- pyenv 1.2.18-7-gae4d4893
- Server version: Apache/2.4.37 (centos)
WSGI(Web Server Gateway Interface)について
PythonのwebアプリケーションをapacheやNginxといったwebサーバーと併用するときに必要となるInterfaceがWSGIというものです。WSGIは、webサーバーからのリクエストをバックエンドのPython webアプリケーションに飛ばします。そして、リスポンスが、webサーバーを介してクライエントに返されます。また、staticファイルに関しては、webサーバーが直接アクセスような仕組みにすることができます。WSGIの仕様に関しては、PEP 3333でまとまっています。
参考:
PEP 3333を日本語訳しました
Secrets of a WSGI master
Flaskのdeployに関する公式ホームページにはWSGIに関して、mod_wsgi (Apache)
を利用した例も挙げられていますが、今回は、Gunicornを使って設定しました。'
pipenvのコマンド例
# 仮想環境のPATH
pipenv --venv
/home/centos/.local/share/virtualenvs/flask-xxxxxx
# 仮想環境のpythonインタプリタ
pipenv --py
/home/centos/.local/share/virtualenvs/flask-xxxxxx/bin/python
# 仮想環境の生成&必要packageのinstall
pipenv install
# 仮想環境の削除
pipenv --rm
# 仮想環境のactivate
pipenv shell
pipenvを使うことで、pythonの仮想環境を構築することができます。仮想環境の場所は、デフォルトだと$HOME/.local/share/virtualenvs/
以下に設定されますが、PIPENV_VENV_IN_PROJECT=true pipenv install
とすると、カレントディレクトリ以下に.venv
が生成されます。
Flaskの設定
簡易的に次のようなディレクトリ構成だとします。
tree .
.
├── Pipfile
├── Pipfile.lock
.
.
.
├── app.py
└── gunicorn_config.py
開発時には、pipenv run python app.py
でbuild in サーバーが起動することを確認します。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0')
Gunicornの設定
gunicornは、コマンドでも指定できますが、次のような設定ファイルを読み込ませることも可能です。特に重要なのは、bindでgunicornの起動portの指定とworkersの数を設定することでしょうか。accesslog = '-'
やerrorlog = '-'
はコンソールへの出力を意味します。
bind = '127.0.0.1:8000'
backlog = 2048
workers = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2
umask = 0
errorlog = '-'
loglevel = 'info'
accesslog = '-'
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
参考:
gunicorn/examples/example_config.py
サービスの設定
サービスが停止したら、3秒後に再起動する設定を入れています。
ExecStartは、絶対パスで指定します。
gunicornは、-c
オプションで、設定ファイルを読み込みます。
app:app
は、app.pyのappを指定しています。
[Unit]
Description=Python Flask App
After=network-online.target
[Service]
User=centos
WorkingDirectory=/var/www/html/flask
ExecStart=/var/www/html/flask/.venv/bin/gunicorn -c gunicorn_config.py app:app
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
注意:
今回は、pythonの仮想環境をプロジェクトのディレクトリで管理する設定にしています。
Apacheの設定
proxyPass
で、クライエントから/
にアクセスが来たら、http://127.0.0.1:8000/
にリクエストを飛ばします。ProxyPassReverse
を設定することで、Flask App内のリダイレクト処理を適切に行います。
<VirtualHost *:80>
ServerName your.domain.name.com
ProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
</VirtualHost>
トラブルシューティング
flaskのurl_for
のredirectがhttp://127.0.0.1/8000/hoge
のようになってしまう
これは、クライエントからHTTPSで通信する時に発生するエラーで、次のようにrequestが送られていることが原因です。
Browser -----HTTPS----> Reverse proxy -----HTTP----> Flask
例えば、DNSサーバーとしてCloudflare
を使えば、flexible
の設定で、クライアントからの通信は、https、Cloudflare
からwebサーバーへの通信は、httpで行われます(下記参照)。
ここで、Reverse proxy
の役割を果たすapacheのVirtualHost
の設定に次のHeaderを追加すればFlask側でうまく処理してくれます。
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
X-Forwarded-Proto
リクエストヘッダーを使用すると、クライアントがCloudflare
への接続に使用したプロトコル (HTTP または HTTPS) を識別することができます。
参考:
Flask Proxy Setups
Setting X-Forwarded-Proto under Apache 2.4
Flask url_for generating http URL instead of https
How does Cloudflare handle HTTP Request headers?
通信がうまくいかない
firewallやselinuxの設定を確認してみてください。
Author And Source
この問題について(Flask+Pipenv+Gunicorn+Apacheでwebサーバーを構築する), 我々は、より多くの情報をここで見つけました https://qiita.com/____easy/items/1e177fe482f1c9e22ac9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .