使用Docker + Flask + uWSGI + Nginx来创建Web应用程序
如果使用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网络与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
使用Dockerfile构建Flask应用。
将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"]
要求.txt
flask
mysql-connector-python
uwsgi
uWSGI配置文件
通过wsgi-file参数,可以指定Python文件的位置。在这种情况下,指定的Python文件不是Flask框架本身的文件,而是用于调用后续提到的Flask框架的Python文件。
此外,socket定义中的设置是让Python容器使用uwsgi在3031端口进行监听。
[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 可以进行重新表述为:wsgi.py文件。
在与app.py文件相同的层级中,放置用于调用flask主体的python文件。另外,如果采用这种配置方式,需要删除app.py中的app.run的部分。
from app import app
if __name__ == '__main__':
app.run(host="0.0.0.0", port=80)
app.py → 应用程序.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")
网络/容器构建文件
FROM nginx:latest
CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
网络/nginx.conf
由于wsgi正在3031端口上等待,
通过添加以下设置:“server flask(容器名称):3031”,
nginx将把接收到的请求代理到uwsgi。
此外,通过使用「listen 80;」语句,nginx容器被设置为在80端口监听。
# 実行ユーザー
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
访问
