Docker跨网络容器通过名称无法访问端口但IP可访问的问题排查
这问题我之前也碰到过!核心问题大概率出在你的Docker Compose网络配置上,咱们一步步拆解:
为什么会出现「ping通容器名但端口连不上,用IP就行」的奇怪现象?
1. 最可能的原因:两个容器根本不在同一个自定义网络里
你手动创建了my_network,第一个Compose文件里也正确声明了external: true,所以container1确实加入了你创建的那个网络。但第二个Compose文件里的my_network没加external: true——Docker Compose默认会给每个项目创建独立的网络,名字是「项目目录名_网络名」,比如你的第二个Compose放在container2_dir目录下,它会自动创建container2_dir_my_network,和你手动建的my_network完全是两个隔离的网络!
那为什么ping能通?要么是你container1所在的default网络里刚好有个同名容器,要么是Docker DNS出现了混淆解析;而你用IP能访问,大概率是通过主机的端口映射(4000:4000)绕了一圈,不是容器间的直接网络通信。
2. 次要可能性:服务绑定地址不对
如果container2里的服务只绑定了127.0.0.1,那只有容器内部能访问,但你说用IP能连,这个可能性比较低,但可以顺便排查下。
具体修复步骤
1. 修正第二个Docker Compose的网络配置
给第二个Compose里的my_network加上external: true,明确告诉它用你已经创建好的外部网络:
version: "3.9" networks: my_network: external: true # 必须加这行!否则会新建网络 services: container2: image: ... ports: - 4000:4000 networks: - my_network
2. 验证两个容器确实在同一个网络
执行命令确认它们的网络归属:
# 查看container1的网络信息 docker inspect container1 | grep -A5 Networks # 查看container2的网络信息 docker inspect container2 | grep -A5 Networks
输出里应该都能看到my_network,而且IP属于同一个子网。
3. 检查服务绑定地址(可选排查)
进入container2,确认服务监听的是0.0.0.0(允许所有IP访问)而不是127.0.0.1:
netstat -tulpn | grep 4000
如果显示127.0.0.1:4000,赶紧修改服务配置,让它绑定0.0.0.0:4000。
4. 重新测试通信
重启两个容器后,在container1里再试:
# 先确认容器名解析的IP是否正确 nslookup container2 # 测试telnet telnet container2 4000 # 或者用curl curl http://container2:4000
这时候应该就能正常连接了!
内容的提问来源于stack exchange,提问作者KDani

