Flask の app.run() を本番環境で使ってはいけない理由
Flask の app.run() は開発用サーバーを起動するメソッドであり、本番環境で使ってはいけない。その理由と正しい本番デプロイ方法を解説する。
app.run() の問題点
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000) # 本番で使ってはいけないFlask の組み込みサーバー(Werkzeug の開発サーバー)には以下の問題がある。
| シングルスレッド | デフォルトでは同時に1リクエストしか処理できない |
| パフォーマンス | 最適化されておらず、大量のリクエストを捌けない |
| セキュリティ | 本番向けのセキュリティ対策が施されていない |
| 安定性 | 長時間稼働やエラー時の復旧機構がない |
debug=True の危険性
本番で debug=True を設定すると、さらに深刻な問題が発生する。
app.run(debug=True) # 絶対に本番で使わないデバッグモードでは Werkzeug のインタラクティブデバッガが有効になり、エラー画面から任意の Python コードを実行できてしまう。攻撃者にサーバーを完全に乗っ取られる可能性がある。
threaded=True でも不十分
app.run(threaded=True) # マルチスレッドにしても本番には不十分threaded=True で複数リクエストを並行処理できるようになるが、それでも本番環境の要件を満たさない。ワーカー管理、ログ、監視、graceful restart などの機能がない。
正しい本番デプロイ
WSGI サーバーを使う。代表的な選択肢は以下のとおり。
| Gunicorn | 最も一般的。シンプルで使いやすい |
| uWSGI | 高機能だが設定が複雑 |
| Waitress | Windows でも動作する純 Python 実装 |
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:appさらに Nginx をリバースプロキシとして前段に配置するのが一般的である。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Flask の警告メッセージ
Flask 自身も app.run() を本番で使わないよう警告を出している。
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.この警告は無視せず、必ず本番用の WSGI サーバーを使用すること。



