输入提示词:hi claude,我们来写一篇帮助开发者的技术博客吧!起缘是我发现有时候在~/.docker/config.json配置代理的时候,如果配置不当会影响docker compose中同一docker网络下的容器之间的通信,请你以严谨、精简又通俗易懂的语言,写一篇与之相关的技术博客,我将发布到csdn上

📌 问题场景

在使用 Docker Compose 部署多容器应用时,遇到一个诡异的问题:同一 bridge 网络下的容器之间无法通过服务名互相访问,报错 Connection refused 或连接超时。

典型的场景如下:

# docker-compose.yml
services:
  ollama:
    image: ollama/ollama:latest
    networks:
      - mcp-network

  mcp-client:
    image: mcp-client-api:latest
    environment:
      - BASE_URL=http://ollama:11434/v1/  # 通过服务名访问
    depends_on:
      - ollama
    networks:
      - mcp-network

networks:
  mcp-network:
    driver: bridge

按理说,mcp-client 应该能通过 http://ollama:11434 访问同一网络下的 ollama 服务。但实际运行时却连接失败。

🔍 根因分析

排查后发现,问题出在宿主机的 ~/.docker/config.json 文件中配置的 HTTP 代理

{
  "proxies": {
    "default": {
      "httpProxy": "http://proxy.company.com:8080",
      "httpsProxy": "http://proxy.company.com:8080"
    }
  }
}

这个配置有什么问题?

Docker 会将这里的代理设置自动注入到所有新创建的容器中,作为环境变量 HTTP_PROXYHTTPS_PROXY

mcp-client 容器尝试访问 http://ollama:11434 时:

  1. 容器内的 HTTP 客户端检测到 HTTP_PROXY 环境变量
  2. 请求被转发到代理服务器 proxy.company.com:8080
  3. 代理服务器无法解析 Docker 内部的 ollama 主机名
  4. 连接失败!

✅ 解决方案

~/.docker/config.json 中添加 noProxy 配置,将容器服务名和内部网络地址排除在代理之外:

{
  "proxies": {
    "default": {
      "httpProxy": "http://proxy.company.com:8080",
      "httpsProxy": "http://proxy.company.com:8080",
      "noProxy": "localhost,127.0.0.1,ollama,*.local,172.16.0.0/12,192.168.0.0/16,10.0.0.0/8"
    }
  }
}

noProxy 配置说明

说明
localhost,127.0.0.1 本地回环地址
ollama 容器服务名(根据你的 compose 文件调整)
*.local 本地域名
172.16.0.0/12 Docker 默认使用的 B 类私有地址段
192.168.0.0/16 C 类私有地址段
10.0.0.0/8 A 类私有地址段

⚠️ 注意:修改 config.json 后,需要重新创建容器(不只是重启)才能生效。因为环境变量是在容器创建时注入的。

# 重建容器
docker compose down
docker compose up -d

🧪 验证方法

进入容器检查环境变量是否正确:

docker exec -it mcp-client-api sh -c 'echo $HTTP_PROXY && echo $NO_PROXY'

或者直接测试连通性:

docker exec -it mcp-client-api curl http://ollama:11434

📝 最佳实践总结

场景 建议
企业内网需要代理 配置 proxies 的同时务必配置 noProxy
容器间通信 将所有服务名和私有 IP 段加入 noProxy
调试连接问题 首先检查容器内的 HTTP_PROXY/NO_PROXY 环境变量
修改代理配置后 必须重建容器(docker compose down && up),仅 restart 无效

💡 延伸:另一种方案

如果不想修改全局的 ~/.docker/config.json,也可以在 docker-compose.yml 中显式覆盖环境变量:

services:
  mcp-client:
    environment:
      - HTTP_PROXY=
      - HTTPS_PROXY=
      - NO_PROXY=*

将代理设为空或将 NO_PROXY 设为 *,可以让该容器完全不使用代理。


参考资料


希望这篇文章对你有帮助!如有问题欢迎评论交流 👋

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐