Docker Compose实战:从单容器到微服务编排的完整教程
Docker已经成为现代开发的标配,但很多开发者停留在docker run的阶段。当项目需要多个服务协同工作(Web应用+数据库+缓存+消息队列)时,Docker Compose的价值就显现出来了。本文从零开始,带你掌握Docker Compose的核心用法。
什么是Docker Compose?
Docker Compose是一个用于定义和运行多容器Docker应用的工具。你只需要一个YAML文件来配置所有服务,然后一个命令就能启动整个应用栈。
基础示例:Web应用+PostgreSQL+Redis
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- ./src:/app/src # 热重载
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=app
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d app"]
interval: 5s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
volumes:
- redisdata:/data
volumes:
pgdata:
redisdata:
核心概念详解
depends_on + healthcheck:确保数据库完全启动后才启动Web服务。注意:depends_on只控制启动顺序,不保证服务就绪。配合condition: service_healthy才能真正等待。
volumes:数据持久化是关键。将数据库文件和Redis数据映射到命名卷,容器删除后数据不丢失。
networks:默认情况下Compose会创建一个网络,所有服务通过服务名(如db、cache)互相访问。
进阶:多环境配置
# docker-compose.override.yml(开发环境)
services:
web:
build:
context: .
target: development
environment:
- DEBUG=true
ports:
- "8080:8080"
- "9229:9229" # Node调试端口
# docker-compose.prod.yml(生产环境)
services:
web:
image: registry.example.com/myapp:latest
environment:
- DEBUG=false
deploy:
replicas: 3
resources:
limits:
cpus: '1'
memory: 512M
# 开发环境
docker compose up -d
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
实战技巧
1. 热重载开发:使用bind mount将源码目录挂载到容器中,修改代码即时生效。
2. 一键初始化数据:使用init服务在启动时自动创建数据库表:
init:
image: your-app-image
command: python manage.py migrate
depends_on:
db:
condition: service_healthy
profiles:
- init # 只在指定profile时运行
3. 日志管理:使用docker compose logs -f web实时跟踪服务日志。
4. 健康检查:为所有关键服务配置healthcheck,自动重启不健康的容器。
5. 资源限制:生产环境中为每个服务设置CPU和内存限制,防止单个服务拖垮整台机器。
常见问题
Q: 容器间网络不通?A: 检查是否使用了正确的服务名(不是localhost)。内部通信使用服务名,如db:5432。
Q: 数据丢失了?A: 确保关键数据使用命名卷而非匿名卷。
Q: 启动顺序不对?A: 使用healthcheck配合depends_on condition。
Q: 性能问题?A: 检查是否使用了bind mount(开发环境OK,生产环境避免)。

