Docker Compose链接容器主机访问问题:web容器连接被拒绝
解决Docker Compose容器内部访问服务被拒绝的问题
首先,咱们来拆解一下问题的根源:
- 你本地浏览器能访问
lvh.me:3001,是因为本地端口映射把主机的3001端口转发到了google_service容器的3001端口,本地的lvh.me解析到你的本机IP(127.0.0.1),所以能正常访问。 - 但在
web容器内部,test.lvh.me默认会解析到容器自己的127.0.0.1,而google_service是另一个独立的容器,不在web容器的localhost里,自然就会出现连接拒绝的错误。
下面给你几个可行的解决办法,按推荐程度排序:
方法一:直接使用Docker Compose服务名访问(最推荐)
在Docker Compose的默认网络环境中,所有服务容器都可以通过服务名互相访问,无需依赖外部域名或IP。你的google_service服务名就是它的内部DNS别名,所以在web容器内部,直接访问google_service:3001就能连接到目标服务。
如果你的应用代码里硬编码了test.lvh.me:3001,建议修改配置文件,把服务地址改成google_service:3001,这是最符合Docker网络设计的方案。
你可以先验证一下:
- 进入
web容器的终端:docker-compose exec web bash - 尝试用curl访问服务名:
curl google_service:3001
如果能正常返回内容,说明网络连通没问题,只需要调整应用配置即可。
方法二:给web容器添加hosts映射(适配必须用域名的场景)
如果因为业务限制必须使用test.lvh.me这个域名,你可以在web容器的hosts文件里添加一条映射,把域名指向google_service容器的IP或者服务名。
方式A:修改docker-compose.yml配置
在web服务的配置里添加extra_hosts字段,直接把域名映射到服务名(Docker会自动解析服务名到对应容器的IP):
services: web: &web ports: - "3000:3000" env_file: - .env.web links: - google_service extra_hosts: - "test.lvh.me:google_service" # 利用Docker内部DNS解析服务名 google_service: command: bundle exec rails s -b 0.0.0.0 -p 3001 ports: - "3001:3001" environment: RAILS_ENV: development
修改后重启服务:
docker-compose down && docker-compose up -d
方式B:启动容器时手动添加hosts
如果你不想修改compose文件,可以在启动web容器时通过--add-host参数指定映射:
# 先获取google_service容器的IP GOOGLE_SERVICE_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker-compose ps -q google_service)) # 启动web容器并添加hosts docker-compose run --publish 3000:3000 --add-host test.lvh.me:$GOOGLE_SERVICE_IP web
额外检查项
- 确认
google_service容器是否正常运行:
状态应为docker-compose psUp,如果是Exit状态,先排查服务启动失败的问题(比如依赖缺失、端口占用)。 - 确认
google_service容器内的服务确实监听了0.0.0.0:3001:你的启动命令里已经加了-b 0.0.0.0,这部分没问题,避免了只监听localhost导致容器外部无法访问的情况。
内容的提问来源于stack exchange,提问作者John Smith




