Docker部署Go+Nginx+Postgres遇Nginx 502 Bad Gateway问题求助
排查Docker Compose部署中Nginx 502 Bad Gateway(连接上游被拒绝)的问题
针对你遇到的connect() failed (111: Connection refused) while connecting to upstream错误,以下是按优先级排序的排查方向和解决方案:
1. Go应用监听地址错误
这是最常见的触发原因:
- 很多Go应用默认监听
127.0.0.1,但在Docker容器内,该地址仅允许容器内部本地访问,Nginx所在的其他容器无法建立连接。必须修改为监听0.0.0.0,允许所有网卡接入:// 错误写法 http.ListenAndServe("127.0.0.1:8080", nil) // 正确写法 http.ListenAndServe("0.0.0.0:8080", nil) - 确认Go应用监听的端口,与Nginx配置中
upstream段指定的端口完全一致。
2. Docker网络与服务名匹配问题
- 确保Go服务和Nginx处于同一个Docker网络:Docker Compose默认会为所有服务创建并加入一个默认网络,若你手动指定了自定义网络,需保证两个服务都加入该网络。
- Nginx配置中
upstream的主机名必须和Docker Compose里Go服务的service名称完全匹配(Docker DNS通过服务名解析容器IP)。例如:- Compose中Go服务的定义:
services: go-app: build: ./go-app ... - Nginx的upstream配置需对应:
upstream go_backend { server go-app:8080; # 这里的go-app是compose中的服务名 } location / { proxy_pass http://go_backend; }
- Compose中Go服务的定义:
3. Go应用未正常启动或启动过慢
- 查看Go应用容器的日志,确认服务是否成功启动(比如是否因连接PostgreSQL失败导致崩溃):
docker logs <go-app-container-name> - 如果Go应用启动需要加载资源或等待数据库就绪,Nginx可能在服务就绪前发起连接导致502。可以:
- 在Compose中给Go服务添加健康检查,让Nginx仅在服务就绪后转发请求:
go-app: ... healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 5s timeout: 5s retries: 3 - 使用启动脚本(如
wait-for-it)确保Go服务启动完成后再启动Nginx。
- 在Compose中给Go服务添加健康检查,让Nginx仅在服务就绪后转发请求:
4. Nginx配置错误或未生效
- 验证Nginx配置文件语法是否正确:
docker exec <nginx-container-name> nginx -t - 确认Nginx的
proxy_pass指向的upstream配置无拼写错误、端口匹配。 - 检查Nginx容器是否正确暴露了端口(比如Compose中
ports: ["80:80"]),确保你访问的是主机的正确端口。
5. 容器间通信限制
- 虽然Docker默认允许同一网络内的容器通信,但如果主机防火墙或安全组限制了容器网络流量,可能导致连接失败。可以临时关闭主机防火墙测试,或检查Docker网络的iptables规则。
快速验证步骤
在Nginx容器内,尝试直接访问Go服务:
docker exec -it <nginx-container-name> curl http://<go-service-name>:<port>如果返回连接拒绝,说明问题出在Go服务或网络配置;如果能正常返回内容,说明Nginx的
proxy_pass配置有误。进入Go应用容器,验证服务是否在监听正确的地址:
docker exec -it <go-app-container-name> netstat -tulpn输出中应能看到
0.0.0.0:<port>的监听记录。
内容的提问来源于stack exchange,提问作者Egor Adamovich
相关产品推荐
相关产品推荐

