502 Bad Gateway 通常意味着 Nginx 无法连接到后端的 Flask 应用服务,最直接的排查方向是确认后端进程是否存活以及通信 socket 或端口配置是否一致。
先说结论:这个问题绝大多数情况是 Nginx 找不到后端服务地址,或者权限不足无法写入 socket 文件。
- 先确认:后端 Gunicorn 或 uWSGI 进程是否在运行
- 先处理:核对 Nginx 配置中的 upstream 地址与后端监听地址是否完全匹配
- 再验证:查看 Nginx 错误日志获取具体连接失败原因
命令速用版
以下是快速检查服务状态和配置的常用命令,按顺序执行即可定位大部分问题(注意普通用户可能需要 sudo 权限):
# 1. 检查后端进程是否存活
ps -ef | grep gunicorn
# 或
sudo systemctl status myapp
# 2. 检查 Nginx 配置语法
sudo nginx -t
# 3. 查看 Nginx 错误日志(关键)
sudo tail -f /var/log/nginx/error.log
# 4. 检查端口或 socket 监听状态
sudo ss -nlpt | grep 8000
# 或查看 socket 文件
ls -l /run/gunicorn.sock为什么会这样
Nginx 本身不运行 Python 代码,它只是一个反向代理。当请求到达 Nginx 时,它会尝试转发给配置好的上游服务(如 Gunicorn、uWSGI)。如果上游服务没有启动、崩溃了、监听地址配置错误,或者 Nginx 没有权限访问 socket 文件,Nginx 就会收到无效响应,从而返回 502 状态码。
在实际运维中,进程挂掉和 socket 权限问题是最高频的两个诱因。
分步处理
第一步:确认后端服务状态
登录服务器,检查 Flask 对应的 WSGI 服务器进程。如果使用 systemd 管理,运行sudo systemctl status 服务名。如果进程不存在,尝试手动启动看是否有报错,比如依赖缺失或端口被占用。
第二步:核对通信地址与配置
打开 Nginx 配置文件(通常在/etc/nginx/sites-available/),找到proxy_pass或uwsgi_pass指令。确认这里的地址与后端服务实际监听的地址完全一致。注意 socket 文件路径大小写敏感。
以下是一个典型的 Nginx 配置示例(使用 Unix Socket):
upstream flask_app {
server unix:/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://flask_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}对应的 Gunicorn 启动命令示例:
gunicorn `--workers` 4 `--bind` unix:/run/gunicorn.sock myapp:app第三步:检查文件权限
如果使用的是 Unix socket 通信,确保 Nginx 运行用户(通常是www-data或nginx)有权限读写该 socket 文件。可以使用ls -l查看。不要随意使用 777 权限,建议设置为属主可读写,同组可读写:
sudo chown www-data:www-data /run/gunicorn.sock
sudo chmod 660 /run/gunicorn.sock或者在 Gunicorn 启动参数中指定 umask:
gunicorn `--umask` 007 ...第四步:查看错误日志
Nginx 的 502 通常会伴随具体的错误日志。执行sudo tail -n 50 /var/log/nginx/error.log,寻找connect() failed或permission denied等关键词,这会直接指出是连接拒绝还是权限问题。
怎么验证是否生效
完成配置修改后,先执行sudo nginx -t确保语法无误,再sudo systemctl reload nginx。在浏览器刷新页面,或使用curl -I http://你的域名查看返回状态码是否为 200。同时观察 Nginx 错误日志,确认不再新增 502 相关的报错记录。
常见坑
- SELinux 限制:在 CentOS 等开启 SELinux 的系统上,即使文件权限正确,SELinux 策略也可能阻止 Nginx 连接网络或 socket,需检查
/var/log/audit/audit.log。 - 协议不匹配:后端是 HTTP 服务却在 Nginx 用了
uwsgi_pass,或者反之,会导致协议解析错误。 - 监听地址绑定:后端服务只监听了
127.0.0.1,但 Nginx 配置尝试通过公网 IP 连接,或者后端监听了 IPv6 而 Nginx 配置了 IPv4。 - 重启顺序:先启动后端服务,再重启 Nginx,避免 Nginx 启动时后端尚未就绪。
参考来源
- Nginx 官方文档 - 错误日志篇:https://nginx.org/en/docs/ngx_core_module.html#error_log
- Gunicorn 官方文档 - 部署 Nginx:https://docs.gunicorn.org/en/latest/deploy.html#nginx
- Flask 官方文档 - 部署选项:https://flask.palletsprojects.com/en/latest/deploying/