flaskでwebアプリケーションを作成した場合に、pythonを実行したものをそのまま本番運用するのは良くない。そこで今回はユーザーとFlaskの間にnginx, uwsgiを経由させる様な構成を構築する。
イメージ
カレントディレクトリ
本当は整理した方が良い
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