04 Docker Compose
当Agent服务需要Flask处理请求、Redis存储缓存、Nginx进行反向代理时,如果只使用docker run逐个启动容器,就需要分别处理网络、环境变量、端口映射和启动顺序。配置发生变化后,也需要重复调整多条命令。
Docker Compose把这些零散操作收进一个文件里:用一个YAML文件定义整个应用栈,一条命令启动所有服务。
一、compose.yaml
在项目根目录创建compose.yaml:
services:
web:
build: .
ports:
- "8000:5000"
environment:
- REDIS_HOST=redis
redis:
image: redis:alpine该配置定义了一个包含两个服务的应用栈:
web服务:用当前目录的Dockerfile构建镜像,把容器的5000端口映射到宿主机的8000端口redis服务:直接用redis:alpine镜像
启动:
docker compose up执行该命令后,两个容器会一起启动,Compose还会自动创建网络,让它们能够互相通信。web服务可以直接把redis当主机名访问Redis,不需要关心Redis容器的IP地址。
二、核心配置
2.1 services
services用来定义应用里的每个服务。服务名同时也是容器网络里的主机名。
services:
web:
build: .
ports:
- "8000:5000"
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
redis:
image: redis:alpine
nginx:
image: nginx:alpine
ports:
- "80:80"
depends_on:
- web2.2 build
# 用当前目录的Dockerfile构建
build: .
# 指定Dockerfile路径
build:
context: .
dockerfile: Dockerfile.prod2.3 image
# 使用已有镜像
image: redis:alpine
# 构建后打标签
build: .
image: yourusername/my-app:1.02.4 ports
端口映射的写法和docker run -p一致:
ports:
- "8000:5000" # 宿主机8000 → 容器5000
- "443:443" # 宿主机443 → 容器443
- "127.0.0.1:3000:3000" # 只允许本机访问也可以不写宿主机端口,由Docker自动分配:
ports:
- "5000" # Docker随机分配宿主机端口2.5 environment
设置环境变量:
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
- DEBUG=false也可以用.env文件管理环境变量:
# .env
APP_PORT=8000
REDIS_HOST=redis# compose.yaml
ports:
- "${APP_PORT}:5000"
environment:
- REDIS_HOST=${REDIS_HOST}Compose会自动读取同目录下的.env文件。应将.env加入.dockerignore,避免被打包进镜像。
2.6 volumes
Volume可以用于数据持久化,配置写法如下:
services:
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
redis-data:2.7 depends_on
depends_on用来控制服务启动顺序:
services:
web:
build: .
depends_on:
- redis
redis:
image: redis:alpine不过,depends_on只保证启动顺序,不保证依赖服务已经准备好。如果web启动时Redis还未初始化完成,连接仍然可能失败。这个问题需要通过健康检查处理。
三、健康检查
将depends_on和健康检查配合使用,可以等依赖服务真正就绪后再启动:
services:
web:
build: .
ports:
- "8000:5000"
environment:
- REDIS_HOST=redis
depends_on:
redis:
condition: service_healthy
redis:
image: redis:alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s| 配置项 | 说明 |
|---|---|
test | 健康检查命令,返回0表示健康 |
interval | 检查间隔 |
timeout | 每次检查的超时时间 |
retries | 连续失败几次后标记为不健康 |
start_period | 启动宽限期,此期间的失败不计入重试次数 |
配置完成后,Compose会等Redis健康检查通过,再启动web服务。
常用服务的健康检查命令:
# Redis
healthcheck:
test: ["CMD", "redis-cli", "ping"]
# PostgreSQL
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
# HTTP服务
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]四、Compose Watch
开发过程中,如果每次修改代码都需要停止、重建并重启容器,反馈周期会比较长。Compose Watch可以监听文件变化,并自动同步到容器中。
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync+restart
path: .
target: /app
- action: rebuild
path: requirements.txt两种同步策略:
| 策略 | 说明 | 适用场景 |
|---|---|---|
sync+restart | 同步文件到容器内并重启 | 代码改动 |
rebuild | 触发镜像重建 | 依赖文件变动 |
启动时加--watch标志:
docker compose up --watch保存代码修改后,Compose会自动同步并重启容器,不需要手动执行重启流程。修改requirements.txt时会触发镜像重建,因为依赖安装需要重新执行。
五、常用命令
# 启动所有服务(前台)
docker compose up
# 启动所有服务(后台)
docker compose up -d
# 启动并强制重建镜像
docker compose up --build
# 启动并监听文件变化
docker compose up --watch
# 停止所有服务
docker compose down
# 停止并删除数据卷
docker compose down -v
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs -f
# 查看单个服务日志
docker compose logs -f web
# 在运行中的容器里执行命令
docker compose exec web bash
# 验证配置文件
docker compose config六、拆分Compose文件
服务数量增加后,一个compose.yaml会变得较长。使用include可以把配置拆分到多个文件:
# compose.yaml
include:
- path: ./infra.yaml
services:
web:
build: .
ports:
- "8000:5000"
depends_on:
redis:
condition: service_healthy# infra.yaml
services:
redis:
image: redis:alpine
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
volumes:
redis-data:通过include引入的服务会共享同一个网络,仍然可以用服务名互相访问。
七、完整的Agent服务compose.yaml
include:
- path: ./infra.yaml
services:
web:
build: .
ports:
- "${APP_PORT}:5000"
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
redis:
condition: service_healthy
develop:
watch:
- action: sync+restart
path: .
target: /app
- action: rebuild
path: requirements.txt# infra.yaml
services:
redis:
image: redis:alpine
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
volumes:
redis-data:八、总结
Docker Compose常用配置如下:
| 概念 | 作用 |
|---|---|
services | 定义应用的各个服务 |
build | 用Dockerfile构建镜像 |
image | 使用已有镜像 |
ports | 端口映射 |
environment | 环境变量 |
depends_on | 启动顺序 |
healthcheck | 健康检查 |
volumes | 数据持久化 |
develop.watch | 文件监听和热更新 |
使用Compose管理多容器应用,可以减少手动维护多条docker run命令的成本。启动、停止都有固定命令,配置也集中在YAML文件里,便于跟随代码一起进行版本控制。
多容器应用还需要理解网络通信和数据持久化,后续内容会继续说明Docker网络与存储。