2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker + Flask + uWSGI + Nginxでwebアプリを作成する

Posted at

flaskでwebアプリケーションを作成した場合に、pythonを実行したものをそのまま本番運用するのは良くない。そこで今回はユーザーとFlaskの間にnginx, uwsgiを経由させる様な構成を構築する。

イメージ

S__2637830.jpg

カレントディレクトリ

本当は整理した方が良い

root@ubuntu-19:/home/tmcit/app# ls
app.py    deploy.sh           Dockerfile        static     tmp        web
build.sh  docker-compose.yml  requirements.txt  templates  uwsgi.ini  wsgi.py

Docker-compose.yml

flaskコンテナは、docker-networkを通して、nginxとやりとりをするため、ポート開放をする必要はない。(nginx、flask間のやりとりが上手く行かない場合、障害原因を切り分けるために用いよう。)

version: '3'
services:

  flask:
    container_name: flask
    build:
      context: .
      dockerfile: Dockerfile
#    ports:
#      - 80:80
#      - 3031:3031
    restart: always
    tty: true
    volumes:
    - ./flask/requirements.txt /usr/src/app/
    - ./flask/app.py /usr/src/app/app.py
    - ./flask/templates/head.html /usr/src/app/templates/head.html
    - ./flask/static /usr/src/app/static
    environment:
      TZ: Asia/Tokyo


  web:
    container_name: web-server
    hostname: web-server
    build: ./web
    volumes:
    - "./web/nginx.conf:/etc/nginx/nginx.conf"
    - "./tmp/nginx_log:/var/log/nginx"
    ports:
      - "4231:80"
    environment:
      TZ: Asia/Tokyo

flask用dockerfile

flaskとuwsgiは同じコンテナ内で動かす。flaskとuwsgiのインストールは、requirements.txtに書き込む。

FROM shomaigu/flask-base:latest

#RUN apt -y install python3 python3-pip curl wget
#RUN apt autoremove
#RUN pip3 install --upgrade pip setuptools
#RUN mkdir -p /usr/src/app/templates
RUN mkdir -p /var/www/

ADD ./requirements.txt /usr/src/app/
ADD ./app.py /usr/src/app/
ADD ./wsgi.py /usr/src/app/
ADD ./templates /usr/src/app/templates
ADD ./static /usr/src/app/static
ADD ./uwsgi.ini /usr/src/app/
RUN pip3 install --no-cache-dir -r /usr/src/app/requirements.txt


WORKDIR /usr/src/app/
#CMD ["python3", "/usr/src/app/app.py"]

CMD ["uwsgi","--ini","/usr/src/app/uwsgi.ini"]

requirements.txt

flask
mysql-connector-python
uwsgi

uwsgi.ini

wsgi-file=によって、pythonファイルがどこにあるか指定してあげよう。また、この時、指定するpythonファイルは、flask本体のpythonファイルではなく、後述するflask本体を呼び出すためのpythonファイルである。
また、socketで定義しているのは、pythonコンテナがuwsgiを3031でlistenさせるという設定。

[uwsgi]
# pythonモジュールのインポート
app = app:create_app()
module = %(app)

callable = app
master = true
processes = 1

# pythonコンテナはuwsgiを3031でlistenさせる
socket = :3031

# pythonファイル
wsgi-file = /usr/src/app/wsgi.py

logto = /var/log/app-server.log

master = true
processes = 10
vaccum = true
die-on-term = true
max-requests = 100
harakiri = 60

reload-mercy = 5
worker-reload-mercy = 5

ignore-sigpipe=true
ignore-write-errors=true
disable-write-exception=true

wsgi.py

flask本体を呼びだすためのpythonファイル。app.pyと同じ階層に配置する事。
また、この構成にする場合、app.pyのapp.runの記述は削除しておくこと。

from app import app

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=80)

app.py

flaskの本体のファイル
wsgi.pyを作る場合は、app.runをコメントアウト

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, flash, render_template, request, session
import mysql.connector, re
from datetime import timedelta



app = Flask(__name__)


@app.route("/")
def index():
    return render_template('index.html')

@app.route("/about")
def about():
    return render_template('about.html')

@app.route("/event")
def event():
    return render_template('event.html')

@app.route("/event01")
def event01():
    return render_template('event01.html')


#if __name__ == "__main__":
#    app.run(host="0.0.0.0", port=80)
#    app.run(host="0.0.0.0")

web/Dockerfile

FROM nginx:latest

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

web/nginx.conf

wsgiが3031で待機しているため、
「server flask(コンテナ名):3031」
この設定を入れる事によって、nginxが受け取ったリクエストをuwsgiへプロキシする。

また、「listen 80;」によってnginxコンテナが80番でlistenする。

# 実行ユーザー
user  nginx;
# 使用可能process数
worker_processes  1;

# エラーログの設定
error_log  /var/log/nginx/error.log warn;
# processidの格納先
pid        /var/run/nginx.pid;

# イベント処理モジュール
events {
    # 最大接続数
    worker_connections  1024;
}

# http関連のモジュール
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 flask:3031;
    }

    server {
        listen 80;
        charset utf-8;

        location / {
            include uwsgi_params;
            uwsgi_pass uwsgi;
        }

    }
}

起動

docker-compose build
docker-compose up

アクセス

image.png

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?