Compose 架构图是理解多容器协同的“电路图”,核心在于服务间通过网络、依赖顺序、健康检查和卷挂载建立运行契约;需重视 DNS 解析、命名卷隔离与生命周期状态诊断。

Compose 架构图不是装饰画,它是理解多容器协同运行机制的“电路图”。关键不在于记住每个图标形状,而在于看清服务之间如何通过网络、卷积、依赖顺序和生命周期建立真实协作关系。
看懂服务定义背后的运行契约
在 docker-compose.yml 中,每个 service 块不只是配置集合,它声明了一组运行时契约:端口映射是容器与宿主机的通信接口,depends_on 不仅控制启动顺序,更暗示了健康就绪依赖(比如数据库必须先响应连接),healthcheck 则定义了该服务“算不算活”的判断标准。若只写 depends_on: [db] 却没配健康检查,应用可能在 db 容器进程已启、但 PostgreSQL 还未完成初始化时就发起连接,导致启动失败。
- 建议为关键依赖服务显式添加
healthcheck,并配合condition: service_healthy -
restart: unless-stopped和deploy.restart_policy(Swarm 模式)作用层级不同,别混用
抓住网络层——协同发生的物理通道
默认的 default network 是所有服务互通的基础,但它的 DNS 可解析性常被低估:服务名即主机名,curl http://web:8000 在 api 容器里能通,靠的就是 Docker 内置 DNS 将 web 解析为对应容器 IP。一旦自定义网络或启用 network_mode: "host",这个隐式连接就会失效。
- 多个 compose 文件共用网络时,务必用
external: true显式声明,避免重复创建同名网络 - 调试连通性优先用
docker compose exec <service> ping <other-service>,而非直接 curl —— 先确认网络层可达
卷积与状态共享的真实边界
Compose 中的 volumes 不是“共享文件夹”那么简单。命名卷(db-data:)由 Docker 管理路径和权限,绑定挂载(./src:/app/src)则完全暴露宿主机路径——这意味着:同一份代码被多个服务挂载时,修改实时可见;但若两个服务同时写入同一个 SQLite 文件,会因无分布式锁而损坏数据。
- 有状态服务(如数据库、Redis)必须用命名卷,禁止绑定挂载其数据目录
- 开发环境需热重载时,可对代码目录使用绑定挂载,但应禁用服务内文件监听器的自动重启竞争(例如用
--no-deps单独重启 web)
生命周期事件揭示协同时机
Compose 启动过程本质是一系列状态跃迁:Created → Starting → Healthy → Running。而 profiles、extends 和 docker compose up -d --scale worker=3 这些能力,都是在不同阶段介入控制流。例如,profiles: ["test"] 让某个服务默认不启动,只在明确指定 --profile test 时才参与协调,这对隔离测试依赖非常有效。
- 用
docker compose ps --status running,exited快速定位卡在哪个状态的服务 - 结合
docker compose logs -f --since 5m查看最近日志,比盲目重启更能定位协同断裂点

















