Docker Compose服务间通过localhost调用API出现Connect ECONNREFUSED错误
问题根因
每个Docker容器拥有独立的网络命名空间,容器内部的localhost指向的是当前容器自身的回环地址,不会路由到宿主机或其他容器,因此跨容器用localhost调用必然触发连接拒绝错误。
解决方案
1. 替换跨服务调用地址
Docker Compose创建的默认bridge网络自带DNS解析能力,容器内部直接用docker-compose.yml中定义的服务名作为域名即可访问其他服务:
- gateway服务调用ems接口,地址填写
http://ems:3005 - ems服务调用gateway接口,地址填写
http://gateway:3001
无需使用宿主机映射端口,直接用容器自身暴露的业务端口即可。
2. 修正错误配置
你当前配置存在2处可优化的错误:
- 配置中的
link: gateway属于语法错误,正确字段为links,且该字段在Docker Compose v3版本已废弃,默认bridge网络已支持服务名解析,直接删除该配置即可 - 所有服务
environment中配置的跨服务调用URL,需把localhost替换为对应服务名,例如需要被gateway调用的ems服务相关URL配置要改为http://ems:3005
3. 服务监听配置校验
确保你的业务服务启动时监听地址为0.0.0.0而非127.0.0.1,如果监听127.0.0.1,该服务只能被容器自身访问,其他容器无法调用。
排查验证步骤
- 执行
docker compose ps确认所有服务状态为Up,无异常退出 - 进入发起调用的容器内部测试连通性,例如进入gateway容器执行
curl http://ems:3005验证接口是否可通,执行ping ems验证服务名是否可以正常解析 - 执行
docker compose logs <服务名>查看对应服务日志,确认服务正常启动、端口监听正常
修正后的配置示例
version: '3.9' services: gateway: image: servicelayernode_gateway build: context: ./servicelayernode_gateway dockerfile: ./servicelayernode_gateway/Dockerfile ports: - 3001:3001 environment: TZ: America/Toronto NODE_TLS_REJECT_UNAUTHORIZED: 0 FLASK_ENV: development DOCKER_HOST: http://0.0.0.0:3001 # 如需调用ems,对应配置改为如下格式 # EMS_URL: http://ems:3005 URL: http://gateway:3001 ems: image: servicelayernode_service_ems build: context: ./servicelayernode_gateway dockerfile: ./servicelayernode_service_ems/Dockerfile ports: - 3005:3005 depends_on: - gateway environment: TZ: America/Toronto NODE_TLS_REJECT_UNAUTHORIZED: 0 FLASK_ENV: development URL: http://ems:3005 networks: default: driver: bridge
内容的提问来源于stack exchange,提问作者Bipin Kumar
相关产品推荐
相关产品推荐

