第6章:Docker Compose(Multi-Container Applications)
一、导读
1.1 本章学习目标
真实应用由多个服务组成。Docker Compose 用一个 YAML 文件定义多容器应用,一条命令启动所有服务。
本章的核心学习目标包括:
- 掌握 Compose 文件结构:services、networks、volumes。
- 配置服务间通信:DNS 解析、依赖关系。
- 管理数据持久化:Volume 配置。
- 控制启动顺序:depends_on 和健康检查。
1.2 为什么本章如此重要
现代应用通常包含 Web 服务器、数据库、缓存、消息队列等多个服务。手动管理这些服务的启动、网络、存储是极其繁琐的。Docker Compose 让你用声明式的方式定义整个应用栈。
1.3 核心问题引导
Compose 文件中 services、networks、volumes 的关系是什么?
服务间如何通过 DNS 互相访问?
depends_on 会等待服务就绪吗?如何确保依赖服务真正可用?
如何在 Compose 中配置健康检查?
二、核心概念详解
2.1 Compose 文件结构
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
volumes:
pgdata:2.2 服务间通信
Compose 自动创建网络,服务名就是 DNS 主机名:
services:
web:
environment:
- DB_HOST=db # 直接用服务名
- REDIS_HOST=cache# 在 web 容器中
curl http://db:5432 # 直接访问数据库
curl http://cache:6379 # 直接访问缓存2.3 depends_on
services:
web:
depends_on:
db:
condition: service_healthy # 等待健康检查通过
cache:
condition: service_started # 等待启动(不等待就绪)注意:depends_on 只控制启动顺序,不等待服务真正就绪(除非使用 condition: service_healthy)。
2.4 常用命令
docker compose up -d # 后台启动
docker compose down # 停止并删除
docker compose logs -f web # 查看日志
docker compose ps # 查看状态
docker compose exec web bash # 进入容器
docker compose build --no-cache # 重新构建
docker compose up --scale web=3 # 扩展副本三、实战案例
3.1 完整的 Web 应用栈
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
backend:
build: ./backend
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
- REDIS_URL=redis://cache:6379
- KAFKA_BROKERS=kafka:9092
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- ./backend:/app
- /app/node_modules
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
retries: 5
cache:
image: redis:7-alpine
ports:
- "6379:6379"
kafka:
image: confluentinc/cp-kafka:7.4.0
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
ports:
- "9092:9092"
volumes:
pgdata:四、本章小结
Compose 文件定义 services、networks、volumes。
服务间通过 DNS 通信,服务名就是主机名。
depends_on 控制启动顺序,配合健康检查等待就绪。
常用命令:up、down、logs、exec、scale。
五、思考与练习
思考题
Compose 创建的网络和默认 bridge 网络有什么区别?
如果数据库启动很慢,depends_on 能保证应用连接时数据库已就绪吗?
如何在 Compose 中实现服务的热重载?
练习题
编写 docker-compose.yml 包含 Web、数据库、缓存、消息队列。
配置健康检查和依赖关系。
练习启动、停止、查看日志、进入容器调试。