624 Docker Compose 多容器编排
一句话概述:Docker Compose 用一个 YAML 文件定义和管理多个容器,一条命令启动整个应用栈(Web + 数据库 + 缓存),是本地开发和测试环境的标配工具。
核心知识点速查表
| 知识点 | 说明 |
|---|
| 最新版本 | Docker Compose v2.39+(2026年) |
| 规范版本 | Compose Spec v5.0.0 "Mont Blanc" |
| 命令格式 | docker compose(空格,不是 docker-compose 横杠) |
| 配置文件 | compose.yaml(推荐)或 docker-compose.yml |
| 新特性 | watch(热重载)、Bake(构建工具)、GPU 支持 |
| 适用场景 | 本地开发、测试环境、CI/CD、小型部署 |
一、安装与基本概念
# Docker Desktop 已内置 Compose(无需单独安装)
docker compose version # 查看版本
# Linux 服务器单独安装
sudo apt install docker-compose-plugin # Ubuntu/Debian
1.1 核心概念
白话解释:
- Service(服务) = 一个容器的定义(如 web、db、redis)
- Network(网络) = 容器之间的通信通道(同网络内用服务名访问)
- Volume(卷) = 数据持久化(容器删了数据还在)
- Profile(配置集) = 按需启动部分服务(如只启动开发工具)
二、基本使用
2.1 最简配置
# compose.yaml
services:
web: # 服务名(可自定义)
image: nginx:alpine # 使用的镜像
ports:
- "8080:80" # 宿主机8080 → 容器80
volumes:
- ./html:/usr/share/nginx/html # 挂载本地目录到容器
docker compose up # 前台启动(Ctrl+C 停止)
docker compose up -d # 后台启动(推荐)
docker compose down # 停止并删除容器
docker compose ps # 查看运行中的服务
docker compose logs -f web # 查看 web 服务的日志(实时跟踪)
2.2 完整应用栈(Web + 数据库 + 缓存)
# compose.yaml - 典型的全栈应用配置
services:
# ---- Web 应用 ----
app:
build: # 从 Dockerfile 构建
context: . # 构建上下文(Dockerfile 所在目录)
dockerfile: Dockerfile # Dockerfile 文件名
ports:
- "3000:3000" # 映射端口
environment: # 环境变量
- DATABASE_URL=postgresql://user:pass@db:5432/mydb # db 是服务名(自动解析为容器 IP)
- REDIS_URL=redis://redis:6379
depends_on: # 依赖关系(先启动 db 和 redis)
db:
condition: service_healthy # 等 db 健康检查通过才启动 app
redis:
condition: service_started # redis 启动就行
volumes:
- ./src:/app/src # 挂载源码(开发时热更新)
restart: unless-stopped # 异常退出时自动重启
# ---- 数据库 ----
db:
image: postgres:17-alpine # PostgreSQL 17
environment:
POSTGRES_USER: user # 数据库用户名
POSTGRES_PASSWORD: pass # 数据库密码
POSTGRES_DB: mydb # 数据库名
volumes:
- postgres_data:/var/lib/postgresql/data # 数据持久化(命名卷)
ports:
- "5432:5432" # 映射端口(方便本地工具连接)
healthcheck: # 健康检查
test: ["CMD-SHELL", "pg_isready -U user"] # 检查命令
interval: 5s # 每5秒检查一次
timeout: 3s # 超时3秒
retries: 5 # 失败5次才算不健康
# ---- 缓存 ----
redis:
image: redis:8-alpine # Redis 8
ports:
- "6379:6379"
volumes:
- redis_data:/data # 持久化 Redis 数据
# 命名卷(容器删了数据还在)
volumes:
postgres_data: # PostgreSQL 数据卷
redis_data: # Redis 数据卷
2.3 使用 .env 文件
# .env 文件(compose.yaml 自动读取)
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret123
POSTGRES_DB=production_db
APP_PORT=3000
# compose.yaml 中引用
services:
db:
image: postgres:17-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER} # 引用 .env 变量
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
app:
ports:
- "${APP_PORT}:3000" # 端口也可以用变量
三、常用操作命令
# 生命周期管理
docker compose up -d # 后台启动所有服务
docker compose up -d app # 只启动 app 服务(含依赖)
docker compose down # 停止并删除容器和网络
docker compose down -v # 同上,并删除数据卷(危险!数据丢失)
docker compose stop # 停止服务(不删除容器)
docker compose start # 启动已停止的服务
docker compose restart app # 重启指定服务
# 查看状态
docker compose ps # 查看服务状态
docker compose ps -a # 包括已停止的
docker compose logs -f # 查看所有日志
docker compose logs -f app db # 只看 app 和 db 的日志
docker compose top # 查看容器进程
# 执行命令
docker compose exec app bash # 进入 app 容器的 shell
docker compose exec db psql -U user mydb # 进入数据库
docker compose run --rm app npm test # 临时启动容器运行测试
# 构建
docker compose build # 构建所有需要构建的镜像
docker compose build --no-cache app # 不使用缓存重新构建 app
docker compose up -d --build # 启动并重新构建(常用)
四、高级用法
4.1 多环境配置(Override)
# compose.yaml - 基础配置
services:
app:
build: .
environment:
- NODE_ENV=production
# compose.override.yaml - 开发覆盖(自动加载)
# 白话:compose.yaml + compose.override.yaml 自动合并
services:
app:
environment:
- NODE_ENV=development # 覆盖为开发模式
volumes:
- ./src:/app/src # 开发时挂载源码
ports:
- "3000:3000"
- "9229:9229" # 调试端口
# 指定使用生产配置
docker compose -f compose.yaml -f compose.prod.yaml up -d
4.2 Watch 模式(热重载)
# compose.yaml
services:
app:
build: .
develop:
watch: # 文件变化自动同步/重建
- action: sync # 文件同步(不重建镜像)
path: ./src # 监听的本地路径
target: /app/src # 同步到容器的路径
- action: rebuild # 变化时重新构建镜像
path: package.json # 监听 package.json
docker compose watch # 启动 watch 模式
# 白话:修改代码后自动同步到容器,不用手动重启
4.3 Profiles(按需启动)
services:
app:
build: .
ports:
- "3000:3000"
db:
image: postgres:17
profiles: [] # 无 profile = 始终启动
# 调试工具(只在需要时启动)
adminer:
image: adminer # 数据库管理界面
ports:
- "8080:8080"
profiles:
- debug # 属于 debug profile
mailhog:
image: mailhog/mailhog # 邮件测试工具
ports:
- "1025:1025"
- "8025:8025"
profiles:
- debug # 属于 debug profile
docker compose up -d # 只启动 app 和 db
docker compose --profile debug up -d # 启动所有服务(含调试工具)
4.4 网络配置
services:
frontend:
image: nginx
networks:
- frontend_net # 只在前端网络
api:
build: .
networks:
- frontend_net # 前端和后端都能访问
- backend_net
db:
image: postgres:17
networks:
- backend_net # 只在后端网络(前端无法直接访问)
networks:
frontend_net: # 前端网络
backend_net: # 后端网络
# 白话:db 只在 backend_net,frontend 无法直接连 db,更安全
4.5 资源限制
services:
app:
build: .
deploy:
resources:
limits:
cpus: '2.0' # 最多用2个CPU核心
memory: 1G # 最多用1GB内存
reservations:
cpus: '0.5' # 预留0.5个CPU
memory: 256M # 预留256MB内存
五、常见报错与解决
| 问题 | 解决 |
|---|
port is already allocated | 端口被占用,改映射端口或 lsof -i :端口号 找进程 |
network xxx not found | docker compose down 清理后重新 up |
| 容器启动顺序不对 | 使用 depends_on + condition: service_healthy |
| 数据卷权限问题 | 在 Dockerfile 中设置 USER 或 chown |
| 修改 compose.yaml 不生效 | 需要 docker compose up -d(自动检测变化并重建) |
六、速查表
| 操作 | 命令 |
|---|
| 启动 | docker compose up -d |
| 停止 | docker compose down |
| 查看状态 | docker compose ps |
| 查看日志 | docker compose logs -f 服务名 |
| 进入容器 | docker compose exec 服务名 bash |
| 重新构建 | docker compose up -d --build |
| 运行命令 | docker compose run --rm 服务名 命令 |
| 扩容 | docker compose up -d --scale 服务名=3 |
| 热重载 | docker compose watch |
| 清理全部 | docker compose down -v --rmi all |
七、同类工具对比
| 特性 | Docker Compose | Kubernetes | Podman Compose | Docker Swarm |
|---|
| 复杂度 | 低 | 极高 | 低 | 中 |
| 编排规模 | 单机 | 集群 | 单机 | 集群 |
| 学习曲线 | 低 | 高 | 低 | 中 |
| 生产部署 | 小型 | 大型 | 小型 | 中型 |
| 配置格式 | YAML | YAML | YAML | YAML |
选型建议:本地开发/小型部署选 Docker Compose;大规模生产集群选 Kubernetes;无 Docker 环境选 Podman Compose。
参考资料:Docker Compose 文档 | Compose Spec | GitHub