一、先说结论(一定要先看)
如果你只记住下面 7 句话,这一篇就已经学会了:
1️⃣ Docker Compose 是“系统描述文件”,不是命令集合。
2️⃣ Compose 解决的是:多容器系统如何稳定、可复现地启动。
3️⃣ Compose 的本质,是对 Docker API 的一层工程封装。
4️⃣ Docker SDK = Compose 的“底层语言”。
5️⃣ healthcheck + depends_on,是多服务系统的生命线。
6️⃣ network + volume,是 Docker 里的“安全域 + 数据域”。
7️⃣ 你能用 SDK 复刻 Compose,才算真正理解 Docker。
从这一篇开始,你用 Docker 的方式,会 从“会跑”升级为“会设计”。
二、为什么 Docker 04 必须升级?
在 Docker 04,我们已经跑通了真实链路:
Browser
↓
Nginx(反向代理)
↓
FastAPI(业务)
↓
PostgreSQL(数据)
但如果你是用 docker run:
- 启动顺序靠记忆
- 网络关系靠经验
- 卷和端口散落在命令里
- 系统“不可复现”
docker run 只能跑“容器”,跑不了“系统”
三、Docker Compose 是在“干什么”?
一句话解释:
Docker Compose = 用一份 YAML,把整个系统描述清楚
它关注的是:
| 维度 |
Compose 解决什么 |
| 服务 |
谁依赖谁 |
| 网络 |
谁能访问谁 |
| 数据 |
哪些数据必须持久 |
| 启动 |
什么时候才算“就绪” |
四、Docker Compose 安装(新环境 · 官方方式)
在 Rocky Linux 9 这类新系统上安装其实很简单:
dnf install docker-compose-plugin
docker compose version
Docker Compose version v5.0.2
只要能看到版本号,就说明:
Compose 已作为 Docker 官方插件集成,无需单独安装
新环境 统一使用:
docker compose up -d
docker compose down
不再推荐 docker-compose 二进制方式。
五、Docker 05 · Compose 实战(完整版)
1️⃣ Compose 目录结构

这是一个 可交付、可复制、可上线 的最小系统。
2️⃣ docker-compose.yml(完整版)
services:
postgres:
image: postgres:16-alpine
container_name: psql
environment:
POSTGRES_DB: appdb
POSTGRES_USER: appuser
POSTGRES_PASSWORD: pass123
volumes:
- psql-data:/var/lib/postgresql/data
networks:
- db-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
interval: 5s
timeout: 5s
retries: 5
fastapi:
build: ./fastapi
image: fastapi-demo:1.0
container_name: fastapi
environment:
DB_HOST: psql
DB_PORT: 5432
DB_NAME: appdb
DB_USER: appuser
DB_PASSWORD: pass123
depends_on:
postgres:
condition: service_healthy
networks:
- db-net
- back-net
expose:
- "8000"
nginx:
build: ./nginx
image: nginx-demo:1.0
container_name: nginx-web
ports:
- "8080:80"
volumes:
- nginx-conf:/etc/nginx/conf.d:ro # 具名挂载(只读)
depends_on:
- fastapi
networks:
- front-net
- back-net
healthcheck:
test: ["CMD-SHELL", "nginx -t && wget -qO- http://fastapi:8000/ >/dev/null 2>&1 || exit 1"]
interval: 10s
timeout: 3s
retries: 5
volumes: # 配置具名卷
psql-data:
nginx-conf:
networks:
front-net:
driver: bridge
back-net:
driver: bridge
db-net:
driver: bridge
3️⃣ 通过Compose启动
docker compose up -d
启动结果:

访问正常:http://host:8080/users

六、Compose 文件的“工程含义”拆解
1️⃣ healthcheck ≠ running
pg_isready -U appuser -d appdb
容器 running ≠ 服务可用
Compose 用 healthcheck 才能判断“服务已就绪”。
2️⃣ depends_on + service_healthy
depends_on:
postgres:
condition: service_healthy
这是真正意义上的 启动顺序控制。
3️⃣ 三张网络 = 三个安全域
| 网络 |
作用 |
| front-net |
对外入口 |
| back-net |
应用通信 |
| db-net |
数据库隔离 |
Docker 网络,本质就是 最小暴露面原则。在微服务架构中,合理规划网络是实现服务隔离与安全通信的基础。
4️⃣ 具名卷 + 只读挂载
- nginx-conf:/etc/nginx/conf.d:ro
配置即资产,必须只读保护。关于持久化存储和配置管理的更多实践,可以参考运维与测试板块的讨论。
七、Compose SDK:Compose 的“底层真相”
Compose 并没有魔法
它只是帮你 批量调用 Docker API
下面这部分,是 Compose 的“反编译版”。
八、Docker SDK 版本 · 完整工程结构

main.go,就是 一个完整的 Compose 替代实现。
九、SDK 版本做了哪些 Compose 做的事?
1️⃣ 网络(等价 compose networks)
ensureNetwork(ctx, cli, NetFront)
ensureNetwork(ctx, cli, NetBack)
ensureNetwork(ctx, cli, NetDB)
SDK 中 必须手动创建 bridge 网络。这与传统虚拟机或物理机的 网络与系统 配置思路有相通之处,都旨在建立可控的通信环境。
2️⃣ 数据卷(等价 compose volumes)
ensureVolume(ctx, cli, VolPSQL)
ensureVolume(ctx, cli, VolNginx)
数据生命周期 独立于容器。
3️⃣ healthcheck(完全等价)
Healthcheck: &containertypes.HealthConfig{
Test: []string{"CMD-SHELL", fmt.Sprintf("pg_isready -U %s -d %s", DBUser, DBName)},
Interval: 5 * time.Second,
Timeout: 5 * time.Second,
Retries: 5,
},
SDK 里你可以清楚看到:
Compose 的每一行,最终都会变成 API 字段。
4️⃣ depends_on 的真实实现
Compose 的:
depends_on:
postgres:
condition:service_healthy
在 SDK 中,被你手动实现为:
waitHealthy(ctx, cli, CPsql, 90*time.Second)
Compose 帮你写的代码,你现在亲手写了一遍
5️⃣ 多网络容器(首网卡 + attach)
netCfg := &networktypes.NetworkingConfig{
EndpointsConfig: map[string]*networktypes.EndpointSettings{
NetDB: {},
},
}
然后:
connectNetwork(ctx, cli, NetBack, fastID)
这就是 Compose 中的底层真相:
networks:
- db-net
- back-net
6️⃣ Nginx 配置卷挂载
hostCfg := &containertypes.HostConfig{
Mounts: []mount.Mount{
{
Type: mount.TypeVolume,
Source: VolNginx, // nginx-conf
Target: "/etc/nginx/conf.d", // 容器内路径
ReadOnly: true, // :ro
},
},
}
等价于:
volumes:
- nginx-conf:/etc/nginx/conf.d:ro
7️⃣通过 Compose SDK启动
生成 go.mod 文件:
go mod init compose-sdk
默认生成如下内容:
module compose-sdk
go 1.24.10
go.mod bin版本:
module compose-sdk
go 1.24.10
require (
github.com/docker/docker v28.5.2+incompatible
github.com/docker/go-connections v0.6.0
)
补齐所需依赖:
go mod tidy
运行main.go:
go run .

访问页面:

十、Compose vs SDK:工程视角对比
| 维度 |
Compose |
Docker SDK |
| 可读性 |
⭐⭐⭐⭐⭐ |
⭐⭐ |
| 可维护性 |
⭐⭐⭐⭐⭐ |
⭐⭐⭐ |
| 自动化 |
⭐⭐ |
⭐⭐⭐⭐⭐ |
| 学习价值 |
⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
| 工程本质 |
描述 |
实现 |
Compose 是“给人用的” SDK 是“给系统用的”
十一、本篇你真正该带走的 3 件事
1️⃣ Compose 不是工具,是 系统工程抽象。
2️⃣ healthcheck 决定系统“生死”,不是装饰。
3️⃣ 当你能用 SDK 复刻 Compose,Docker 才算理解透彻。
希望这篇从实战到原理的拆解,能帮你建立起对容器编排更系统的认知。如果你想探讨更多关于 云原生 或基础设施即代码的实践,欢迎来云栈社区交流。