docker compose 多容器网络需按通信边界划分、按角色连接、按安全要求控制互通,禁用默认网络,通过自定义 bridge 网络隔离 frontend、backend、data 和 monitoring,服务仅接入必需网络实现最小权限。

用 Docker Compose 配置多容器复杂网络,关键不是堆功能,而是按通信边界划网络、按服务角色连网络、按安全要求控互通。默认的单网络太“大锅饭”,生产环境必须拆。
明确划分网络层级,按职责隔离
前端、后端、数据库、监控等服务不该挤在一个网里。比如 Web 服务只需暴露 HTTP,不该直接连数据库;数据库更不该被外部网关直连。通过定义多个自定义 bridge 网络,把服务按逻辑分组:
- frontend:只放 API 网关、Nginx、静态资源服务
- backend:放业务微服务(如 user-svc、order-svc)
- data:专供 MySQL、Redis、Elasticsearch 等数据组件
- monitoring:给 Prometheus、Grafana、Fluentd 独立网络,方便采集且不干扰业务
服务按需接入一个或多个网络
不是“所有服务都加进所有网”,而是谁需要和谁说话,才让它们同网。典型场景:
- API 网关(如 Traefik)同时接入 frontend 和 backend,做流量入口和内部路由
- 业务服务(如 app)接入 backend 和 data,读写数据库
- 数据库(如 postgres)只接入 data,不对外暴露任何网络路径
- 监控服务(如 prometheus)只接入 monitoring,再通过 backend 的 metrics 端点拉取数据(需显式配置 network 列表)
用 networks 字段精准控制连接关系
在 docker-compose.yml 中,networks 是根级字段,定义网络;每个 service 下的 networks 是列表,指定它加入哪些网。示例:
version: '3.8'
services:
traefik:
image: traefik:v2.10
networks: [frontend, backend]
app:
image: myapp:latest
networks: [backend, data]
db:
image: postgres:15
networks: [data]
prometheus:
image: prom/prometheus
networks: [monitoring, backend] # 拉取 backend 服务指标
networks:
frontend:
driver: bridge
backend:
driver: bridge
data:
driver: bridge
monitoring:
driver: bridge
这样,db 容器就完全无法被 traefik 或宿主机 ping 通,除非经过 app 中转 —— 这就是最小权限原则的落地。
避免默认网络陷阱,禁用自动 default 网
默认生成的 <project>_default</project> 网络会把所有没指定 networks 的服务全塞进去,破坏隔离设计。解决办法:
- 每个 service 显式声明
networks,不依赖默认行为 - 若想彻底禁用 default 网,可加
networks: {}根级空定义(Docker Compose v2.20+ 支持),或确保所有 service 都有明确 network 列表 - 检查网络是否生效:
docker network ls查看实际创建的网络名;docker network inspect <name></name>看容器接入情况











