1. 介绍
Flask 是一个 WSGI应用程序。WSGI服务器用于运行应用程序,将传入的 HTTP 请求转换为标准的 WSGI 环境,并将传出的 WSGI 响应转换为 HTTP 响应。
WSGI协议: Web框架致力于如何生成HTML代码,而Web服务器用于处理和响应HTTP请求。Web框架和Web服务器之间的通信,需要一套双方都遵守的接口协议。WSGI协议就是用来统一这两者的接口的。
WSGI容器: 常用的WSGI容器有Gunicorn和uWSGI,但Gunicorn直接用命令启动,不需要编写配置文件,相对uWSGI要容易很多,所以这里我也选择用Gunicorn作为容器。
gunicorn: 是一个python Wsgi http server,只支持在Unix系统上运行,来源于Ruby的unicorn项目。Gunicorn使用prefork master-worker模型(在gunicorn中,master被称为arbiter),能够与各种wsgi web框架协作。
nginx: 使用gunicorn时试图将其绑定到80或者443端口,发现无效。如果想绑定到这些端口,常见的有如下的几种方法:
- 使用Nginx代理转发。
- sudo启动gunicorn。
- 安装额外的程序。
2. 环境
- OS: Ubuntu 20.04.1
- Python version: 3.8.10
- Flask version: 2.0.1
- Gunicorn version: 20.1.0
- Nginx version: 1.18.0
3. 安装部署
3.1 python3与pip3安装
1 | # 确定python3已经安装 |
3.2 创建虚拟环境
1 | mkdir flask-gunicorn # 创建项目文件夹 |
3.3 安装flask gunicorn
1 | pip3 install flask gunicorn |
3.4 创建Flask Web Application
1 | mkdir flask-blog && cd flask-blog/ |
创建html模板文件夹
1 | mkdir templates && cd templates/ |
在模板文件夹下创建index.html
1 |
|
项目根目录下创建app.py脚本
1 | from flask import Flask, render_template |
启动应用
1 | python3 app.py |
3.5 配置Gunicorn
项目根目录下创建wsgi.py
文件,作为应用程序的接入点
1 | from app import app |
项目目录结构如下:
1 | . |
启动Gunicorn
option | detail |
---|---|
-w | 指定服务器worker的个数 |
–bind | 指定接口和端口,接口0.0.0.0将是服务器的公网IP |
1 | gunicorn -w 4 --bind 0.0.0.0:8999 wsgi:app |
将Gunicorn配置为系统服务
use Gunicorn as systemd service 将gunicorn修改为系统服务,这样即可通过systemd启停服务,并跟随服务器开机自动启动.
首先,创建一个以.service
结尾的 /etc/systemd/system/my-flask.service
文件,添加内容如下:
1 | [Unit] |
- 该系统服务会在
network
服务up之后启动 User
和Group
可以根据全选需要适当选择,这里选择了最高权限的root用户用户组,与nginx通信也可只选择www-data用户组WorkingDirecotry
指定了 flask web app所在的路径Environment
指定了flask web app所需虚拟环境的路径ExecStart
包含通过gunicoron启动服务的命令,以及其他所需命令unix:/tmp/my-server/ipc.sock wsgi:app
是socket接口,用来与gunicron服务通信(interpersonal communication, IPC), 当服gunicorn启动服务的时候生成该socket文件,服务停止时即删除,也因此将产生的socket文件存放在/tmp
目录下。同时,Nginx可以通过这个产生的socket文件与gunicorn通信
1 | mkdir /tmp/flask-server |
如果出现任何错误,可以通过
journalctl -u my-server.service
命令,并按Ctrl+G
查看日志输出,可根据错误信息排查问题。
通过Supervisor 配置 Gunicorn(Configure Gunicorn as Supervisor)
除了将Gunicron服务配置为系统守护进程,可以选择Supervisor监控服务
1 | # 先停systemd 守护进程 |
修改配置文件/etc/supervisord/supervisord.conf
1 | [supervisord] |
同时在/etc/supervisord/supervisord.d/
路径下,添加gunicorn.conf
配置文件:
1 | [program:flask_catalog] |
1 | supervisord # 启动 |
3.6 配置Nginx
1 | sudo apt install nginx |
Nginx相关文件存放在/etc/nginx/nginx
路径下,需要修改nginx配置文件,将nginx作为flask web app 的代理。nginx.conf
是主要配置文件,通常开发人员或系统管理员不会修改此配置文件,新的配置文件会在sites-available/
目录下修改,并链接到/sites-enabled/
目录下。因此可在sites-available/
目录下创建配置文件my-flask
:
1 | server { |
执行 nginx -t
确保配置文件语法正确,无误之后建立符号链接
1 | sudo nginx -t |
1 | nginx -s reload |
以上配置使nginx监听8999端口,代理连接生成的socket文件,gunicorn可以从socket文件读取数据并允许flask web app 产生响应,然后gunicorn将flask web app的响应的数据写到socket文件,提供给nginx读取并返回用户
验证nginx代理请求,http://ip:8999
,会得到响应
配置Nginx服务域名
通过server_name
给服务添加域名,添加一行配置如下:
1 | server { |
然后在/etc/hosts
添加域名解析,或者搭建配置DNS服务器便于查找域名
1 | ... |
故障排查
sudo journalctl -u SERVICE
检查系统服务相关的错误- 查看
supervisord
日志文件,提供了stderr_logfile
和stdout_logfile
,可以查看相关的错误 /var/log/nginx/access.log
and/var/log/nginx/error.log
可查看nginx相关错误
总结
介绍了采用Gunicorn和Nginx部署flask应用的过程,利用gunicorn和nginx的并发性可以简单的对其配置文件进行扩展。
参考
https://www.golinuxcloud.com/flask-gunicorn-nginx/
https://wizardforcel.gitbooks.io/the-way-to-flask/content/chapter013.html