Docker Compose 进阶指南:如何在不同项目间共享网络 在微服务开发中,我们经常遇到这样的场景:**项目 A**(如主业务系统)和 **项目 B**(如独立的工具服务、MCP Server)位于不同的代码仓库,由不同的 `docker-compose.yml` 管理,但它们需要通过内网互相通信。 本文将介绍如何优雅地打通两个 Docker Compose 项目的网络,并避开常见的“坑”。 ## 核心原理 Docker 网络隔离是基于 Network Namespace 的。要让两个独立 Compose 项目通信,必须让它们的容器加入**同一个** Docker Network。通常的做法是:**一方负责创建(Create),另一方负责引入(External)。** ### 第一步:创建共享网络(项目 A) 假设项目 A 是主服务(如 LobeChat),我们在其 `docker-compose.yml` 中显式定义一个带名字的网络。 ```yaml # Project A: docker-compose.yml services: app: image: my-app networks: - shared-net networks: shared-net: driver: bridge # 关键:显式指定网络名称,避免 Docker 自动加上项目名前缀(如 project_shared-net) name: my-global-network ``` 启动项目 A 后,Docker 会创建一个名为 `my-global-network` 的网桥。 ### 第二步:引入外部网络(项目 B) 项目 B(如 Calendar MCP)不需要创建网络,而是声明使用已存在的外部网络。 ```yaml # Project B: docker-compose.yml services: mcp-server: image: my-mcp ports: - "3001:3000" # HTTP mode MCP server networks: - app-net # 在 Service 内部引用下面的网络键名 networks: app-net: external: true # 关键:告诉 Docker 这个网络已经存在 name: my-global-network # 必须与项目 A 中定义的 name 完全一致 ``` ### 第三步:服务互访(DNS 解析) 进入Project A,也就是my-app, * **调用地址**:`http://my-mcp:3000` 而不是3001端口 ## 避坑指南(血泪经验) ### 1\. Project B的监听地址必须是 `0.0.0.0` 否则 Connection Refused 这是最容易被忽视的问题。 需要看看Project B的.env或者代码是否有类似:`HOST: 0.0.0.0` 之类的环境变量。 ### 2\. 网络启动顺序 如果你重建了项目 A(`docker compose down && up`),Docker 会删除旧网络并创建一个**同名但 ID 不同**的新网络。 此时,项目 B 的容器仍连接在旧 ID 上,导致处于“断网”状态。 * **表现**:`wget: bad address`。 * **解决**:依次重启项目 A、B 的容器,让它重新查找并加入新的网络 ID。 ### 3\. 特殊网络模式 (`network_mode`) 如果你的服务使用了 `network_mode: service:xxx`(附属容器模式),你不能在该服务下定义 `networks`(包括 extra_hosts、ports、networks 等)。否则配置冲突失败。 来自 大脸猪 写于 2025-11-28 23:59 -- 更新于2025-11-29 00:04 -- 0 条评论