想要配置好 Apache + mod_wsgi + Flask 问题真是太多了,随便换一个 Linux 发行版,或者不同的 Python 版本就得让 Google 排很多温室气体。Nginx 可以使用 uWSGI 和 Flask 串联起来,配置起来第一直觉好像也不容易,所以打算换一种方式,直接用一个 Python 的 WSGI HTTP Server, 必要的话再往前面加一个反向代理的 Nginx。这里就来试下 Nginx + Gunicorn + Flask 的完整配置。
在 Flask 的官方网站 Deployment Options 提到了各种生产环境下的部署办法,与 Gunicorn 类似的工具还有 uWSGI, Gevent, Twited Web, Hypercorn, Uvicorn, Daphne(来自于 django)
安装 Gunicorn
用 yum 或 apt 可以直接安装 gunicorn
, 但可能会安装到不是自己的 Python 版本用的,我会选择用 Python 虚拟环境中的 pip 来安装
pip install gunicorn
Flask Hello World程序
照例,需要一个 Flask 最简单的的程序来演示,文件命名为 hello_world.py
, 内容为
1 2 3 4 5 6 7 |
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello World!' |
由于不直接启动该 Flask 应用,可不加 Flask 的启动代码
1 2 |
if __name__ == '__main__': app.run() |
加了也无妨,因为接下来要通过 gunicorn 来启动 hello_world.py
的话,__name__
不再是 __main__
了,也就不会执行 app.run()
代码的。
该 Gunicorn 上场了
命令如下,并启动后命令行显示
$ gunicorn -w 3 hello_world:app
[2020-07-18 05:54:09 +0000] [12779] [INFO] Starting gunicorn 20.0.4
[2020-07-18 05:54:09 +0000] [12779] [INFO] Listening at: http://127.0.0.1:8000 (12779)
[2020-07-18 05:54:09 +0000] [12779] [INFO] Using worker: sync
[2020-07-18 05:54:09 +0000] [12781] [INFO] Booting worker with pid: 12781
[2020-07-18 05:54:09 +0000] [12782] [INFO] Booting worker with pid: 12782
[2020-07-18 05:54:10 +0000] [12783] [INFO] Booting worker with pid: 12783
hello_world:app
为模块名:Flask 对象, 默认启动在 8000 端口上,试下访问服务
$ curl localhost:8000
Hwllo World!
gunicorn --help
会显示出大量的启动参数,简单说明 gunicorn
命令的常用参数
- -w, --workers: 启动多个个 worker
- -b, --bind: 绑定到 IP 和端口,默认为 127.0.0.1:8000, 比如可以 -b 0.0.0.0:80
- --reload: 代码有变化时自动重启 Worker
- -D, --daemon: 这个很有用,把 gunicorn 服务在后台启动
- -u, --user; -g, --group: 启动时用的用户名和用户组
- --access-logfile, --error-logfile, ...... 等很多日志相关的参数
- --keyfile, --certfile, ..... gunicorn 可以配置启用 HTTPS 服务
- -c, --config: 可以把所有的配置放在一个配置文件中去
为了下面的 Nginx 反向代理,我们把 gunicorn 放到后台去,且不用暴露 gunicorn 服务(绑定在 127.0.0.1:5000 上),命令为
$ gunicorn -D -w 5 -b 127.0.0.1:5000 main:app
如果不使 Nginx 的话,可以用 gunicorn 把服务启动 0.0.0.0:80 上
使用 Nginx 反向代理本地的 Gunicorn 服务
在 Nginx 配置文件,比如 /etc/nginx/conf.d/default.conf
中加上
1 2 3 4 5 6 7 8 9 10 11 |
server { listen 80; server_name test.yanbin.blog; location / { proxy_pass http://127.0.0.1:5000; proxy_redirect off; proxy_set_header Host $host:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } |
对 test.yanbin.blog
域名的访问代理到 http://127.0.0.1:5000
上去。试下
$ curl test.yanbin.blog
Hello World!
现在对外的服务都由 Nginx 来管理了,如果要启用 HTTPS 服务,也只需要在 Nginx 单方面配置,Nginx 与 Gunicorn 服务(Flask 就用) 之间是本地通信。
链接:
- 生产环境利gunicorn部署Flask的python web服务
- nginx+uwsgi 和nginx+gunicorn区别、如何部署
- Flask 部署项目nginx + gunicorn + flask
- 阿里云部署 Flask + WSGI + Nginx 详解
本文链接 https://yanbin.blog/nginx-gunicorn-flask-integration/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。