Docker 系列(七):用 Compose 编排多容器应用
2026年7月22日 · 13 分钟
为什么需要 Compose
上一篇里,跑一个「应用 + 数据库」要手动 docker network create、两三条冗长的
docker run,还得记住一堆参数。要是再加个 Redis 缓存呢?管理起来简直噩梦。
Docker Compose 用一个 docker-compose.yml 文件,把整套服务、网络、数据卷声明式
地定义好,然后:
docker compose up -d # 一条命令,全部启动
docker compose down # 一条命令,全部停止清理
提示:新版 Docker 已内置
docker compose(带空格,v2 插件)。老的docker-compose(带横线,独立命令)仍可用,命令基本一致。
compose 文件结构
看一个「Web 应用 + PostgreSQL + Redis」的完整例子:
services:
# Web 应用(用当前目录的 Dockerfile 构建)
web:
build: .
ports:
- "8080:3000"
environment:
- DATABASE_URL=postgres://postgres:secret@db:5432/app
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
restart: unless-stopped
# 数据库(直接用现成镜像)
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=app
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Redis 缓存
cache:
image: redis:7-alpine
restart: unless-stopped
# 具名数据卷(由 Compose 管理)
volumes:
pgdata:
短短几十行,就定义了三个服务、它们的依赖关系、健康检查和数据持久化。
关键字段逐个讲
services —— 定义每个容器
每个 service 就是一个容器。两种来源:
web:
build: . # 用本地 Dockerfile 构建
db:
image: postgres:16 # 直接拉现成镜像
自动组网:服务名即主机名
这是 Compose 最爽的地方:同一个 compose 文件里的服务,会被自动放进一个网络,
可以直接用服务名互访。上面 web 里写的 db:5432、cache:6379,其中 db、cache
就是服务名——不用再手动 docker network create,Compose 全帮你做了。
depends_on —— 启动顺序与健康等待
depends_on:
db:
condition: service_healthy
让 web 等到 db 健康后再启动。注意:不加 condition 的 depends_on 只保证「启动
顺序」,不保证 db 真的「准备好接受连接」——所以要配合下面的 healthcheck。
healthcheck —— 健康检查
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s # 每 10 秒检查一次
timeout: 5s # 超过 5 秒算失败
retries: 5 # 连续 5 次失败才算 unhealthy
Docker 定期运行检测命令,判断容器是否真正「可用」,而不只是「进程还活着」。
volumes、environment、restart
volumes:挂载数据卷,文件底部要在顶层volumes:里声明具名卷。environment:设置环境变量,也可用env_file: .env从文件读取。restart: unless-stopped:容器挂了自动重启,除非你手动停。
常用命令
docker compose up -d # 后台启动全部服务
docker compose up -d --build # 强制重新构建镜像再启动
docker compose down # 停止并删除容器、网络
docker compose down -v # 连数据卷一起删(慎用,会丢数据)
docker compose ps # 查看服务状态
docker compose logs -f # 跟踪所有服务日志
docker compose logs -f web # 只看 web 服务
docker compose exec web sh # 进入 web 服务容器
docker compose restart web # 重启单个服务
docker compose pull # 拉取最新镜像
用 .env 管理配置
把敏感信息和可变配置抽到 .env 文件,别硬编码进 compose:
# .env 文件
POSTGRES_PASSWORD=secret
APP_PORT=8080
# docker-compose.yml 里用 ${} 引用
services:
web:
ports:
- "${APP_PORT}:3000"
db:
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
Compose 会自动读取同目录下的 .env。记得把 .env 加进 .gitignore,别提交到仓库。
一个真实的开发流程
# 首次启动整套环境
docker compose up -d
# 改了代码,重新构建并更新
docker compose up -d --build
# 看某个服务出了什么问题
docker compose logs -f web
# 进容器调试
docker compose exec web sh
# 今天不干了,全部停掉(数据卷保留)
docker compose down
本篇小结
- Compose 用一个 YAML 声明式定义多服务,
up/down一键起停整套环境。 - 同一 compose 文件的服务自动组网,直接用服务名互访。
depends_on + healthcheck控制启动顺序并等待依赖真正就绪。- 用
.env+${变量}管理配置,敏感信息不入库。
现在你已经能编排一整套应用了。最后一篇进入生产级话题:镜像瘦身、多阶段构建、 安全加固——把前面所有知识收束成可上线的最佳实践。