Docker容器间HTTP调用报Connection refused 外部可访问问题
问题根因
核心是Docker网络隔离机制导致的地址指向错误,和服务本身逻辑无关:
- 每个Docker容器拥有独立的网络命名空间,容器内部的
127.0.0.1/localhost默认指向当前容器自身,既不是宿主机,也不是其他容器。你的服务里把调用地址写死为http://127.0.0.1:8082,在human_cloning_app容器内发起请求时,实际是在访问当前容器自己的8082端口,该端口没有服务监听,自然会报Connection refused错误。 - 本地IDE运行时两个服务都直接跑在宿主机网络栈上,127.0.0.1指向宿主机,所以通信正常;Postman从宿主机发起请求时,走的是Docker Compose配置的
ports端口映射规则,所以也能正常访问两个服务。 - 另外你当前Compose配置的端口映射和你描述的对外访问地址不匹配:你写的human_cloning_facilities映射宿主机8080、jedi_service映射宿主机8082,和你描述的“jedi_service对外8080、human_cloning对外8082”正好相反,不过这个问题不影响容器间通信故障的判断。
- 同一份Docker Compose部署的容器默认会加入同一个专用桥接网络,容器之间可以直接通过Compose中定义的服务名作为内网域名互相访问,不需要走宿主机端口映射。
解决方法
按以下步骤修改即可恢复通信:
- 修改服务调用地址
将Feign客户端中配置的被调服务地址从http://127.0.0.1:8082改为http://jedi_service:8082。其中jedi_service是Compose文件中定义的jedi服务的服务名,Docker内置DNS会自动将该域名解析到对应容器的内网IP,直接走容器内网通信,不需要依赖端口映射。注意:容器间内网通信直接使用服务容器内部监听的端口即可,和
ports配置中映射的宿主机端口没有关系,ports配置仅用于给宿主机提供访问入口。 - 修正Compose端口映射(按需修改)
如果你需要宿主机访问两个服务的地址和你描述的一致(jedi_service用8080、human_cloning用8082),调整ports配置即可,修正后的完整Compose配置参考:
version: "3.9" services: human_cloning_facilities: image: erwanlt94/human_cloning_app:6.0.0 container_name: human_cloning_app restart: unless-stopped ports: - "8082:8080" # 宿主机8082端口映射到human_cloning容器内部8080端口 jedi_service: image: erwanlt94/jedi_api:1.0.0 container_name: jedi_service restart: unless-stopped ports: - "8080:8082" # 宿主机8080端口映射到jedi_service容器内部8082端口 volumes: human_cloning_facilities: driver: local jedi_service: driver: local
- 配置优化建议
不要将服务调用地址硬编码在代码中,推荐通过Spring配置项、环境变量的方式按部署环境注入地址:- 本地开发环境(IDE直接启动):配置调用地址为
http://127.0.0.1:8082 - Docker部署环境:配置调用地址为
http://jedi_service:8082
可以结合Spring Profile功能实现不同环境自动切换配置,不需要修改代码即可适配多环境部署。
- 本地开发环境(IDE直接启动):配置调用地址为
内容的提问来源于stack exchange,提问作者Erwan Le Tutour
相关产品推荐
相关产品推荐

