Flask 部署后报 502 Bad Gateway Nginx 配置错误怎么查

文章导读
502 Bad Gateway 通常意味着 Nginx 无法连接到后端的 Flask 应用服务,最直接的排查方向是确认后端进程是否存活以及通信 socket 或端口配置是否一致。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

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_passuwsgi_pass指令。确认这里的地址与后端服务实际监听的地址完全一致。注意 socket 文件路径大小写敏感。

Flask 部署后报 502 Bad Gateway Nginx 配置错误怎么查

以下是一个典型的 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-datanginx)有权限读写该 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() failedpermission 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/