docker compose 中定义了一个容器,名字叫 us4ever.com,而你在真实世界(比如 DNS 中)也有一个域名叫 us4ever.com。这就涉及到了 Docker 内部 DNS 和外部 DNS 的解析优先级问题。
下面我来分段说明容器内访问 us4ever.com 时会发生什么情况:
一、Docker Compose 的服务名会自动注册为内部 DNS 名
在 docker-compose.yml 中定义了如下服务:
1services:
2 us4ever.com:
3 image: some-imageDocker 会把这个服务名 us4ever.com 注册到 Docker 的内部 DNS 中。这样,同一网络下的其他容器访问 us4ever.com,默认会解析成这个服务对应的容器的 IP 地址。
二、容器内访问 us4ever.com 的优先级是内部 DNS 优先
在容器内执行:
1ping us4ever.com或者程序代码中访问 http://us4ever.com,Docker 默认会先查自己的内部 DNS,看有没有名为 us4ever.com 的容器或服务。
由于你的容器名就是 us4ever.com,所以会解析到容器内部网络中的地址,比如 172.18.0.2。
这意味着:容器内访问 us4ever.com 实际上访问的是容器自己或是 Docker 网络中的服务,而不是公网的 us4ever.com 域名。
三、如果你想在容器中访问公网的 us4ever.com 怎么办?
你有以下几种方案:
方法一:修改服务名,避免和公网域名冲突
最简单直接的方法是避免使用和公网域名一样的服务名。比如你可以改成:
1services:
2 us4ever-app:
3 image: some-image这样容器内部访问 us4ever.com 就会走公网 DNS,不会被 Docker 截获。
方法二:容器内通过公网 IP 或 hosts 文件强制指定
如果你确实需要服务名是 us4ever.com,但还想在容器内访问真实公网的 us4ever.com,可以:
-
使用公网 IP:
1curl http://<真实公网IP> -
修改
/etc/hosts:在容器内运行(或者 Dockerfile 中添加):
1echo "1.2.3.4 us4ever.com" >> /etc/hosts这会让容器内的
us4ever.com指向你指定的 IP,而不是 Docker DNS。
方法三:使用 extra_hosts 显式绑定
你也可以在 docker-compose.yml 中添加:
1services:
2 us4ever.com:
3 image: some-image
4 extra_hosts:
5 - "us4ever.com:1.2.3.4" # 指定公网 IP这样容器内访问 us4ever.com 时,就会直接跳过 Docker 的 DNS,解析到 1.2.3.4。
总结:
- Docker Compose 会把服务名注册到内部 DNS,容器内优先解析内部 DNS。
- 如果服务名和公网域名一样,容器内访问会“被劫持”,指向内部网络。
- 要想访问真实公网域名,可以改服务名、使用
extra_hosts或修改容器内/etc/hosts。