flask应用必须通过nginx反向代理对外服务,因flask run默认仅监听127.0.0.1:5000;生产环境需用gunicorn启动并绑定127.0.0.1:8000,nginx通过proxy_pass转发请求,同时配置proxy_set_header透传x-real-ip、host等头信息,并用proxyfix中间件正确解析真实ip与协议。

Flask应用如何配合Nginx做反向代理?
直接用 flask run 启动的服务默认只监听 127.0.0.1:5000,外部无法访问,Nginx 反向代理是必须环节。关键不是“能不能配”,而是必须把 Flask 绑定到 0.0.0.0 且关闭调试模式上线。
- 启动 Flask 时显式指定 host 和 port:
app.run(host='0.0.0.0', port=8000, debug=False)(生产环境禁用debug=True) - Nginx 配置里
proxy_pass必须指向这个地址,例如http://127.0.0.1:8000 - 务必加
proxy_set_header透传原始请求头:proxy_set_header X-Real-IP $remote_addr;和proxy_set_header Host $host;,否则 Flask 的request.remote_addr和url_for()会出错 - 静态文件(如 CSS/JS)建议由 Nginx 直接服务,不要走 Flask,配置
location /static指向磁盘路径
Nginx负载均衡怎么分发到多个Flask进程?
单个 Flask 进程是阻塞的,靠多进程或 Gunicorn/Uvicorn 才能并发;Nginx 负载均衡只是把请求打到后端多个地址上,它不负责启动 Flask 实例——那是你用 gunicorn 或 systemd 管理的事。
- 先用
gunicorn --bind 127.0.0.1:8000 --workers 4 myapp:app启 4 个 worker,再另起一个监听127.0.0.1:8001,以此类推 - Nginx 的
upstream块定义后端池:upstream flask_backend {<br> server 127.0.0.1:8000;<br> server 127.0.0.1:8001;<br> server 127.0.0.1:8002;<br>} - 默认轮询(round-robin),如需 session 粘滞,加
ip_hash;——但 Flask 默认 session 依赖客户端 cookie,只要 secret_key 一致,其实不需要粘滞 - 别忘了在
location /里用proxy_pass http://flask_backend;,而不是写死单个地址
为什么访问时出现 502 Bad Gateway?
90% 是 Flask 进程根本没起来,或端口被占用、防火墙拦截、绑定地址错误。Nginx 日志(/var/log/nginx/error.log)里搜 connect() failed 就能定位。
- 检查 Flask 是否真在监听:运行
netstat -tuln | grep :8000,确认有tcp6 0 0 127.0.0.1:8000这一行 - 如果 Flask 绑的是
localhost,某些系统解析为 IPv6 地址,而 Nginx 用 IPv4 连不上——统一用127.0.0.1更稳妥 -
proxy_read_timeout默认 60 秒,若 Flask 处理耗时较长(如文件上传、报表生成),要调大,否则 Nginx 主动断连返回 502 - SELinux 开启时可能拦截 Nginx 连本地端口,临时关掉验证:
setenforce 0
Flask里如何正确获取用户真实IP和协议?
不靠 Nginx 透传,request.remote_addr 永远是 127.0.0.1;url_for() 生成的链接也可能是 http:// 而非 https://,因为 Flask 不知道外面套了 HTTPS 反代。
- 确保 Nginx 配置包含:
proxy_set_header X-Forwarded-For $remote_addr;和proxy_set_header X-Forwarded-Proto $scheme; - Flask 中读取真实 IP:
request.headers.get('X-Forwarded-For', request.remote_addr).split(',')[0].strip() - 强制使用 HTTPS 链接:
app.config['PREFERRED_URL_SCHEME'] = 'https',但前提是 Nginx 已设置X-Forwarded-Proto - 更健壮的做法是用
ProxyFix中间件(来自 Werkzeug):from werkzeug.middleware.proxy_fix import ProxyFix<br>app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
,它会自动处理X-Forwarded-*头
ProxyFix 或手动解析 X-Forwarded-For,导致日志和限流逻辑拿到的全是 127.0.0.1;另一个隐形坑是多个 Flask 实例用了不同 secret_key,结果 session 解密失败,用户反复登出。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











