核心问题是“连不上”“找不到”“通不过”:先确认容器是否在同一网络(如统一配置自定义network),再验证服务名能否被DNS正确解析(用nslookup测试),最后检查目标服务是否监听0.0.0.0而非127.0.0.1并确保端口可达。

多容器网络不通,核心问题通常出在“连不上”“找不到”“通不过”三个环节。排查不靠猜,关键看三件事:容器是否在同一个网络里、服务名能不能正确解析、端口有没有真正暴露并监听。
确认所有服务是否共用同一网络
Docker Compose 默认为每个项目创建独立桥接网络,但若服务未显式声明网络,可能被分配到不同网络甚至默认 bridge 网络——而默认 bridge 不支持服务名解析。
- 运行 docker network ls 查看当前项目网络,确认是否存在项目专属网络(如 myapp_default)
- 对每个服务执行 docker inspect <container_name> | grep -A 5 "Networks",核对 Networks 下的网络名称是否一致
- 若发现服务分散在不同网络,统一在 docker-compose.yml 中声明自定义网络,例如:
app-net:
driver: bridge
并在各服务下添加:
networks:
- app-net
验证服务名能否被正确解析
容器间通信依赖内置 DNS。即使 IP 能 ping 通,服务名解析失败也会导致应用层调用失败(尤其是 Go/Java 等语言的 HTTP 客户端)。
- 进入一个容器:docker-compose exec web sh
- 执行 nslookup api 或 getent hosts api,看是否返回目标容器的 IP(应与 docker network inspect 中查到的 IP 一致)
- 若解析失败或返回 127.0.0.1/::1,说明 DNS 机制异常——常见于 Docker for Mac 旧版本、自定义 resolv.conf 覆盖、或 Go 应用启用 cgo 导致绕过容器 DNS
- 临时验证:在 Go 代码中加日志打印 net.LookupHost("api") 结果,对比容器内 nslookup 输出
检查端口暴露与应用监听地址
端口映射(ports)只影响宿主机访问;容器间通信走的是内部网络,不经过端口映射,但要求目标服务**监听在 0.0.0.0 上**,而非仅 127.0.0.1。
- 确认服务配置了 ports(对外暴露需要),但更关键的是检查容器内应用是否绑定 0.0.0.0:8080 而非 127.0.0.1:8080
- 在目标容器中执行:netstat -tuln | grep :8080 或 ss -tuln | grep :8080,确保监听地址是 0.0.0.0 或 ::
- 从源容器测试连通性:curl -v http://api:8080/health(注意用服务名+内部端口,不用映射端口)
- 若 curl 超时但 nslookup 成功,大概率是应用未监听、防火墙拦截(容器内 iptables 极少见,但某些精简镜像含 drop 规则)、或服务启动慢于调用时机


















