Docker Compose 生产环境最佳实践:从开发到部署的完整配置

Docker Compose 不只是本地开发工具。合理配置后,它完全可以胜任中小规模的生产部署。

一、多环境配置分离

不要把所有配置写在一个 docker-compose.yml 里。推荐分层:

# docker-compose.yml - 基础配置
services:
  app:
    image: myapp:latest
    restart: unless-stopped
    networks:
      - backend

  db:
    image: mysql:8.0
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend

networks:
  backend:

volumes:
  db_data:
# docker-compose.prod.yml - 生产覆盖
services:
  app:
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  db:
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
    secrets:
      - db_root_password

启动时:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

二、健康检查

生产环境必须配置健康检查,否则 Docker 不知道服务是否真正可用:

services:
  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  db:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

配合 depends_on 的条件依赖:

services:
  app:
    depends_on:
      db:
        condition: service_healthy

三、密钥管理

不要在 docker-compose.yml 里硬编码密码。使用 Docker Secrets 或环境变量文件:

secrets:
  db_root_password:
    file: ./secrets/db_password.txt

services:
  db:
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
    secrets:
      - db_root_password

或者用 .env 文件:

# .env
DB_PASSWORD=your_secure_password
APP_PORT=8080
services:
  app:
    ports:
      - "${APP_PORT}:8080"

四、日志管理

生产环境的日志必须有轮转策略:

services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"

如果需要集中日志,可以用 fluentdsyslog driver。

五、资源限制

防止某个容器耗尽主机资源:

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M

六、网络隔离

前端只能访问后端 API,不能直接访问数据库:

networks:
  frontend:
  backend:

services:
  nginx:
    networks:
      - frontend
      - backend

  app:
    networks:
      - backend

  db:
    networks:
      - backend

七、备份策略

数据库卷的备份:

# 备份
docker compose exec db mysqldump -u root -p dbname > backup.sql

# 或者直接备份卷
docker run --rm -v db_data:/data -v $(pwd):/backup alpine \
  tar czf /backup/db_backup_$(date +%Y%m%d).tar.gz -C /data .

八、零停机更新

# 拉取新镜像
docker compose pull

# 逐个重启服务
docker compose up -d --no-deps --build app

对于无状态服务,可以配合 Nginx 做蓝绿部署。

Docker Compose 的简洁性是它的优势。不需要 Kubernetes 的复杂性,合理配置就能满足大多数中小项目的生产需求。