引入env文件后Docker Compose容器间连接被拒绝问题求助
问题背景
使用Docker Compose部署.NET微服务架构,引入存储密钥、连接字符串等敏感信息的env文件后,发布流程无异常提示(Docker Compose任务、Portainer及容器日志均无报错),但主入口容器无法连接部分容器,直接返回Connection Refused(无超时或未知主机错误)。重启故障容器后恢复,且每次发布后均为相同容器出现问题。环境为Hyper-V上的Ubuntu 20.04,Docker版本20.10.17,发布命令为docker-compose -p demo up -d --build,部分Compose配置如下:
services: service1: image: service1 hostname: service1.hostname build: context: . dockerfile: ./service1.Dockerfile env_file: - service1.env service2: image: service2 hostname: service2.hostname build: context: . dockerfile: ./service2.Dockerfile ports: - 15443:443 env_file: - service2.env
服务通过配置的hostname(如https://service1.hostname)通信,部署由Azure发布流水线自托管代理执行。
排查与解决方案
1. 确认服务是否正常监听端口
Connection Refused通常意味着目标容器的服务未在预期端口监听,而非网络无法连通:
- 进入故障容器,执行
ss -tulpn(或netstat -tulpn),检查服务进程是否在监听指定端口(如443)。 - 查看.NET应用的详细启动日志(若未输出到容器控制台,可检查应用内的日志文件),确认服务启动时是否因配置加载失败(如env文件未正确读取)导致初始化异常,进而未启动监听端口。
2. 添加服务启动依赖与健康检查
引入env文件后,服务加载配置的耗时可能增加,导致依赖服务提前启动并发起请求。通过健康检查确保目标服务完全就绪后再启动依赖服务:
修改Compose配置,为服务添加健康检查,并配置依赖条件:
services: service1: # 原有配置 healthcheck: # 根据你的ASP.NET Core健康检查端点调整,若为HTTP则改用http://localhost/health test: ["CMD", "curl", "-f", "https://localhost/health"] interval: 10s timeout: 5s retries: 5 start_period: 30s # 给服务预留足够的启动初始化时间 service2: # 原有配置 depends_on: service1: condition: service_healthy
3. 移除手动Hostname配置
Docker Compose默认网络支持通过服务名(如service1)直接进行服务发现,手动配置hostname可能引入DNS解析冲突或缓存问题:
- 删除Compose中所有
hostname字段,修改服务通信地址为服务名(如https://service1),避免自定义hostname导致的解析异常。
4. 调整发布命令,强制容器/网络重建
旧容器或网络的缓存可能导致配置未正确刷新,修改发布命令确保完全重建:
- 先清理旧容器、网络与卷,再重新构建启动:
docker-compose -p demo down -v docker-compose -p demo up -d --build
- 或直接强制重建容器:
docker-compose -p demo up -d --build --force-recreate
5. 检查Env文件加载正确性
- 确认
env文件格式正确:键值对无多余空格,特殊字符使用正确引号包裹(如CONN_STR="Server=...;Password=...")。 - 进入容器执行
printenv,检查环境变量是否正确加载,确保.NET应用能读取到所需的敏感配置。
6. 升级Docker版本
当前使用的Docker 20.10.17版本较旧,部分网络或Compose相关bug可能已在新版本中修复,建议升级至最新稳定版(如24.x系列)。
内容的提问来源于stack exchange,提问作者Richárd Gulyás

