【Flask】Docker-Composeを用いてFlask × nginx × uwsgi環境を構築してみた

はじめに

こんにちは、がんがんです。
現在、実験のデモとしてFlaskとRaspberry Piを用いたデモを作成しております。
開発の環境は主にWindowsで作成しているものの、実際に動作させるのはラズパイ環境を想定しています。

ですので、スムーズに環境を移行できるようにDocker Composeを用いてFlaskアプリの環境構築をやってみようと思いました。

目的

  • Docker Composeを用いてFlask × nginx × uwsgiの環境を構築

Githubはこちらです。
github.com

参考

主に下記を参考にしました。下記の方のGitHubこちらに置いておきます。
qiita.com

各ファイルのパラメータの解説が詳しく書かれています
docker + nginx + uwsgi + flask の構築 - ぬブログ

uWSGIについてはこちら
uWSGI入門 - Python学習講座

Internal Server Errorについて
nginxとuwsgiを使っていてInternal Server Errorが発生したとき - ストックドッグ

環境

・ホストOS:Windows 10
・Docker:Docker for Windows
・Python:Python3.7

ファイル構成

基本的には参考記事の通りです。異なるのはsrc直下の構成と./nginx/log/くらいです。
./nginx/log/Internal Server Errorが出ていたので対処として導入しました。

    .
    ├── Makefile
    ├── README.md
    ├── docker-compose.yml
    ├── app
    │   ├── Dockerfile
    │   ├── requirements.txt
    │   ├── src
    │   │   ├── config
    │   │   │   ├── __init__.py
    │   │   │   └── default.py
    │   │   ├── server
    │   │   │   └── __init__.py
    │   │   ├── run.py
    │   │   ├── templates
    │   │       ├── index.html
    │   │       └── test.html
    │   └── uwsgi.ini
    └── nginx
        ├── log
        │   └── ...
        ├── Dockerfile
        └── nginx.conf

docker-compose.ymlのセットアップ

version: "3"
services:

  uwsgi:
    build: ./app
    volumes:
      - ./app:/var/www/
    ports:
      - "3031:3031"
    environment:
      TZ: "Asia/Tokyo"

  nginx:
    build: ./nginx
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/log:/var/log/nginx/
    links:
      - uwsgi
    ports:
      - "5000:80"
    environment:
      TZ: "Asia/Tokyo"

nginxのセットアップ

Dockerfile
FROM nginx

CMD ["nginx", "-g", "daemon off;","-c","/etc/nginx/nginx.conf"]
nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    upstream uwsgi {
        server uwsgi:3031;
    }

    server {
        listen 80;
        charset utf-8;
        
        location /health_check {
           empty_gif;
           access_log off;
           break;
        }

        location / {
            include uwsgi_params;
            uwsgi_pass uwsgi;
        }

        location /static {
           alias /static;
        }

        location /media {
            alias /media;
        }

    }
}

uwsgi・Flaskのセットアップ

Dockerfile
FROM python:3.7.5

RUN mkdir /var/www
# workdirの指定
WORKDIR /var/www

# 依存Pythonライブラリ一覧コピー
COPY requirements.txt ./

# 依存Pythonライブラリインストール
RUN pip install --no-cache-dir -r requirements.txt

WORKDIR /var/www/src

CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]
requirements.txt

Bootstrapについては深い意味はないです。使う予定があったから先に導入した程度の理由です。

Flask
uwsgi
Flask-Bootstrap4
uwsgi.ini
[uwsgi]
wsgi-file = /var/www/src/run.py
callable = app
master = true
processes = 1
socket = :3031
chmod-socket = 666
vacuum = true
die-on-term = true
py-autoreload = 1

Flaskのセットアップはとりあえず基本的なものにしています。

run.py
from server import app

@app.route("/")
def index():
    return "Hello World!!"

if __name__ == "__main__":
    app.run()

プロジェクトの構築および実行

プログラムの準備が出来たら、実際に起動させてみます。makeコマンドが実行できる場合は下記のコマンドで大丈夫です。

$ make run

開発時はまだ整備してなかったので、1コマンドずつ実行していきます。

$ docker-compose build --no-cache
$ docker-compose up -d

起動したのちに指定したポートにアクセスします。下記の画面が表示されていれば問題なく接続できています。

f:id:gangannikki:20200112215120j:plain
実行結果

参考までに(Docker Hubでの検索)

Docker Hubで検索してみたら作っている方がいたので参考までに共有します。
これを使ってみるのもおもしろいかもですね。
https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/

おわりに

今回はFlask+uwsgi+nginxの環境をDocker Composeを用いて作成しました。開発時にInternal Server Errorが何度か発生したのでそちらについては次回メモとしてまとめておきます。