どこにでもいるSEの備忘録

たぶん動くと思うからリリースしようぜ

Flask+WSGI+NginxでサーバーをDocker上で動かすメモ

前に、Flaskでサーバー建てることが結構ありました。 Flaskでサーバーを立てると、こんな感じのワーニングが出るかと思います。

Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.

遊びで使っている分には全然気にしなくていいんですが、ちょっと気になったのでワーニングを消してみます。 これについて、こちらの記事を参考にさせていただきました。

qiita.com

なぜワーニングが出るのか

なにも考えずにFlaskでサーバーを立てると、Flaskの内臓サーバーでサーバーを起動します。 ところが、これがあくまでも検証用の簡易サーバーのため、

本番で使うときにはちゃんとしたサーバー使ってね♡

ってことでワーニングが出るらしいです。へぇー。

WSGI+nginxで内臓サーバーの使用を回避する

さて、ワーニングが出る理由はなんとなくわかったところで本題です。 要するに、下記のようにサーバーの状態を変えてやればOKってことみたいです。

Flask <-> uwsgi <-(uWSGI protocol)-> Nginx <-(HTTP)-> Client

こうやることでnginxとFlask連携させることができます。

Docker imageを探す

この段階でもなんだかめんどくさいそうだなー、、、って思い始めました。 神様みたいな人がDocker Image公開してないかなーって探してみたら、やっぱりありました!!   github.com

こちらを使ってサーバーを立ててみたいと思います。

Pythonのバージョンなどで色々ありますが、一旦Python3.7のものを使っていきたいと思います。 まずはImageをビルドしていきます。

cd uwsgi-nginx-flask-docker-1.2.0/python3.7
docker build -t myimage .

そんでもって、コンテナを起動してみます。 READMEとはちょっと外れますが、docker-composeで書いてみます。

version: "3.7"
services:
  web:
    build: .
    ports:
      - "80:80"

これで動かしてみます。

docker-compose up

http://127.0.0.1にアクセスすると

Hello World from Flask in a uWSGI Nginx Docker container with Python 3.7 (default)

という文言が返ってきました。 なんか普通に動いてそうです。

ログには特に冒頭のwarningも出ていないので、問題なく動作しているようです。

コードを書くには

この辺にも書いてありますが、一応すべてのモジュールを追加したときのディレクトリ構成の例の様になるんですかね。

.
├── app
│   ├── app
│   │   ├── api
│   │   │   ├── api.py
│   │   │   ├── endpoints
│   │   │   │   ├── __init__.py
│   │   │   │   └── user.py
│   │   │   ├── __init__.py
│   │   │   └── utils.py
│   │   ├── core
│   │   │   ├── app_setup.py
│   │   │   ├── database.py
│   │   │   └── __init__.py
│   │   ├── __init__.py
│   │   ├── main.py
│   │   └── models
│   │       ├── __init__.py
│   │       └── user.py
│   └── uwsgi.ini
└── Dockerfile

coreにDBとの接続、apiにエンドポイント周辺の管理、modelに主要な処理を記述する感じでしょうか。 この辺は人それぞれでカスタムしていったら良さそうですね。

その他

多分使うことになるであろうデバッグモードでの起動は下記の様にするみたいです。

docker run -d --name mycontainer -p 80:80 -v $(pwd)/app:/app -e FLASK_APP=main.py -e FLASK_DEBUG=1 myimage flask run --host=0.0.0.0 --port=80

(READMEより転記)

感想

ワーニングは無意識に無視してましたけど、やっぱりちゃんと読まないとだめですね。 反省。