使用Docker + Flask + uWSGI + Nginx来创建Web应用程序

如果使用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网络与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

访问

image.png
广告
将在 10 秒后关闭
bannerAds