必须用gunicorn+nginx组合,因flask自带服务器非生产级;gunicorn专注运行python应用并响应wsgi请求,nginx负责反向代理、ssl终止、静态文件服务、ip透传等网络层任务,二者分工明确、缺一不可。

不能直接用 flask run 上生产,必须拆成 Gunicorn 处理 Python 请求、Nginx 做反向代理——这是唯一被验证过能扛住真实流量的组合。
为什么 gunicorn --bind 127.0.0.1:8000 app:app 启动后 Nginx 访问 502?
最常见原因是 Gunicorn 没绑定到可被 Nginx 访问的地址,或没正确监听。默认 --bind 127.0.0.1:8000 是对的,但必须确认:
-
gunicorn进程是否真在运行?用ps aux | grep gunicorn看; - 端口是否被占用?
sudo ss -tuln | grep :8000; - Ubuntu 22.04 默认启用
systemd-resolved,有时会让127.0.0.1解析失败,换成--bind 127.0.0.1:8000 --backlog 2048更稳; - 如果用
0.0.0.0:8000,Gunicorn 就暴露在公网了,Nginx 的proxy_pass仍应指向127.0.0.1:8000,而不是localhost(DNS 解析可能引入延迟或失败)。
为什么 Nginx 配置里必须加 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for?
Flask 应用里调用 request.remote_addr 时,不加这行拿到的永远是 127.0.0.1,所有用户 IP 都丢失。这不是“锦上添花”,而是日志、限流、风控的基础。
完整最小必要头配置:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
漏掉 X-Forwarded-Proto 会导致 Flask 的 url_for(..., _external=True) 生成 http:// 链接,哪怕你用了 HTTPS。
如何让 Gunicorn 在 Ubuntu 22.04 上开机自启且崩溃后自动重启?
别用 nohup 或 &,必须用 systemd。写一个 /etc/systemd/system/myflaskapp.service:
[Unit] Description=Gunicorn instance for myflaskapp After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/myflaskapp Environment="PATH=/var/www/myflaskapp/venv/bin" ExecStart=/var/www/myflaskapp/venv/bin/gunicorn --workers 3 --bind unix:/run/myflaskapp.sock --chown www-data:www-data app:app Restart=on-failure RestartSec=10
关键点:
-
ExecStart用 Unix socket(unix:/run/myflaskapp.sock)比 TCP 端口更安全、更快,Nginx 的proxy_pass改成http://unix:/run/myflaskapp.sock;; -
Restart=on-failure比always更合理:避免进程因配置错误反复崩溃又重启; -
RestartSec=10防止雪崩式重启,尤其当数据库连不上时; - 务必
sudo chown www-data:www-data /run/myflaskapp.sock,否则 Nginx 无权访问 socket 文件。
为什么 gunicorn --reload 绝对不能出现在生产配置里?
它会监听源码文件变化并热重载,这在生产环境等于主动邀请 DoS 攻击:攻击者只要不断修改 .py 文件时间戳就能触发全量 reload,导致服务中断。它只该出现在开发阶段的 gunicorn.conf.py 中,且必须明确禁用:
reload = False reload_engine = "auto"
真正需要代码更新时,应该走 sudo systemctl restart myflaskapp + sudo systemctl reload nginx,整个过程可控、可审计、有日志。
最容易被忽略的是:Gunicorn 日志默认不落盘,--access-logfile - 只打到 stdout,而 systemd 会截断长日志。上线前必须配好 --access-logfile /var/log/myflaskapp/access.log 和 --error-logfile /var/log/myflaskapp/error.log,并确保目录权限正确。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











