求助:通过NGINX反向代理从宿主机访问Docker Compose容器失败的问题
你好,我来帮你分析下这个问题,看起来是宿主机的Nginx和Docker容器的网络连通性出了问题,咱们一步步来排查解决:
一、先搞懂第一个错误的根源:host not found in upstream "pgadmin"
你在Nginx配置里直接用pgadmin当上游主机名,但宿主机上的Nginx不在Docker Compose创建的专属虚拟网络里。Docker Compose默认会给每个项目生成一个独立的网络,容器名只是这个网络内部的DNS别名,宿主机的进程(比如你的Nginx)根本没法解析这个名字,所以会报“找不到主机”的错误。
二、为什么用127.0.0.1:81还是出现502 Bad Gateway?
你已经把容器的80端口映射到了宿主机的81端口,理论上用http://127.0.0.1:81是能访问的,但502说明Nginx连不上这个上游地址,咱们先从最基础的点排查:
1. 确认容器是否正常运行
在宿主机上执行docker ps,看看pgadmin容器的状态是不是Up,端口映射是不是显示0.0.0.0:81->80/tcp(如果是127.0.0.1:81->80/tcp也没关系,只要宿主机本地能访问就行)。
2. 测试宿主机本地能否直接访问容器
在宿主机上跑curl http://127.0.0.1:81,看看能不能拿到pgAdmin的页面内容:
- 如果本地访问都失败,那问题出在容器本身,去看容器日志:
docker logs pgadmin,检查有没有启动错误(比如配置的邮箱/密码是否合法,容器有没有完成初始化)。 - 如果本地能访问,那问题大概率在Nginx配置或权限上:
- 仔细检查Nginx配置里的
proxy_pass是不是写对了,应该是proxy_pass http://127.0.0.1:81;——从你提供的错误日志看,日志里显示upstream: "http://localhost/",是不是你配置里漏写了端口81? - 查看Nginx的错误日志(一般在
/var/log/nginx/error.log),看看有没有更详细的错误信息,比如“连接被拒绝”之类的提示。
- 仔细检查Nginx配置里的
三、其他可选的解决方案
如果上面的方法没解决问题,还有两种思路可以尝试:
1. 让Docker容器和Nginx共享同一网络(适合Nginx也是Docker部署的场景)
如果你的Nginx是用Docker运行的,可以把它加入到Docker Compose的网络里,这样就能直接用容器名pgadmin作为上游地址了。你可以在compose文件里添加Nginx服务,或者用docker network connect命令把已有的Nginx容器加入到pgadmin所在的网络。
2. 给Docker容器指定静态IP
在Docker Compose里给pgadmin容器分配一个静态IP,然后Nginx配置里用这个IP作为上游地址,示例如下:
version: '3.8' services: pgadmin: container_name: pgadmin image: dpage/pgadmin4 restart: always environment: PGADMIN_DEFAULT_EMAIL: admin@admin.com PGADMIN_DEFAULT_PASSWORD: pw ports: - "81:80" networks: custom_net: ipv4_address: 172.20.0.10 networks: custom_net: ipam: config: - subnet: 172.20.0.0/24
然后把Nginx配置里的proxy_pass改成http://172.20.0.10:80;(这里用容器内部的80端口,不用宿主机映射的81端口),这样宿主机的Nginx就能通过静态IP直接访问容器了。
备注:内容来源于stack exchange,提问作者Johnczek

