Nginx Proxy Pass无法执行,与Gunicorn通信返回502错误求助
解决Nginx反向代理Gunicorn返回502 Bad Gateway的问题
环境与配置
Flask服务代码
from flask import Flask app = Flask(__name__) @app.route('/api/get_latest_api_version', methods=['GET']) def get_latest_api_version(): return "3.0.0" if __name__ == '__main__': app.run(debug=True, host='0.0.0.0')
Gunicorn启动方式
在tmux会话中执行:
python3 -m gunicorn -b 0.0.0.0:5000 app:app --log-level "debug"
Nginx配置(systemd管理)
server { listen 443 ssl; server_name problemsite.ca; ssl_certificate /etc/letsencrypt/live/problemsite.ca/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/problemsite.ca/privkey.pem; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
问题表现
外部通过HTTPS访问时返回502 Bad Gateway,Nginx错误日志示例:
<IP SOURCE> - - [04/May/2024:20:58:31 +0000] "GET /api/get_latest_api_version HTTP/1.1" 502 173 "-" "curl/7.68.0"
测试请求命令:
curl -X 'GET' 'https://problemsite.ca/api/get_latest_api_version' -H 'accept: application/json'
已知信息
- 本地直接访问Gunicorn(
curl http://127.0.0.1:5000/api/get_latest_api_version)正常返回"3.0.0" - Nginx监听443端口正常,SSL证书、域名解析无问题
- 外部请求时Gunicorn无任何调试日志输出
- 服务器为Oracle Linux 8免费实例,无其他冲突Web服务,所有操作以root身份执行
已尝试的无效操作
- 在Nginx的
proxy_pass末尾添加斜杠 - 修改Gunicorn监听地址为127.0.0.1、localhost或其他网卡地址
- 修改
proxy_pass目标为localhost、0.0.0.0或其他网卡地址 - 多台外部机器测试,均返回502错误
排查与解决方案
1. 优先检查SELinux(最可能原因)
Oracle Linux 8默认启用SELinux,会阻止Nginx向本地端口发起网络连接。
临时关闭测试:
setenforce 0
如果此时请求恢复正常,执行以下命令添加永久规则:
setsebool -P httpd_can_network_connect on systemctl restart nginx
2. 验证Gunicorn监听状态
确认Gunicorn确实在监听5000端口:
ss -tulpn | grep 5000
确保输出中存在0.0.0.0:5000或127.0.0.1:5000,且关联进程为Gunicorn。
3. 查看Nginx详细错误日志
检查/var/log/nginx/error.log,定位502错误的具体原因:
- 若日志显示
Permission denied:对应SELinux限制,按步骤1解决 - 若日志显示
Connection refused:检查Gunicorn是否正常启动或监听端口配置错误
4. 将Gunicorn配置为systemd服务(避免tmux会话中断导致进程终止)
创建/etc/systemd/system/gunicorn.service文件:
[Unit] Description=Gunicorn instance for Flask app After=network.target [Service] User=root WorkingDirectory=/path/to/your/app/directory ExecStart=/usr/bin/python3 -m gunicorn -b 127.0.0.1:5000 app:app --log-level debug [Install] WantedBy=multi-user.target
替换/path/to/your/app/directory为app.py所在的实际目录,然后执行:
systemctl daemon-reload systemctl start gunicorn systemctl enable gunicorn
内容的提问来源于stack exchange,提问作者IWantAnswers
相关产品推荐
相关产品推荐

