Docker Compose 最佳实践

Docker Compose 最佳实践指南

Docker Compose是用于定义和运行多容器应用的工具,通过一个docker-compose.yml文件描述应用的所有服务,一条命令启动完整的开发或测试环境。本文分享Docker Compose的最佳实践。

一、docker-compose.yml基础结构

version: '3.8'

services:
  # Web应用服务
  app:
    image: myapp:${APP_VERSION:-latest}  # 使用环境变量,默认值latest
    build:
      context: .
      dockerfile: Dockerfile
      args:
        NODE_ENV: production
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    env_file:
      - .env.production   # 从文件加载环境变量(不放进版本控制)
    depends_on:
      db:
        condition: service_healthy  # 等待数据库健康后才启动
    restart: unless-stopped         # 自动重启策略
    networks:
      - app-net
    volumes:
      - logs:/app/logs
  
  # 数据库服务
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password  # 使用secrets
      MYSQL_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql      # 数据持久化
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql  # 初始化SQL
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - app-net

volumes:
  db_data:    # 命名卷,数据持久化
  logs:

networks:
  app-net:    # 自定义网络,服务间隔离

二、多环境配置管理

# 目录结构
docker-compose.yml          # 基础配置(公共部分)
docker-compose.dev.yml      # 开发环境覆盖
docker-compose.prod.yml     # 生产环境覆盖
.env                        # 默认环境变量(不提交git)
.env.example                # 示例文件(提交git)

# 开发环境覆盖(挂载源码、开启热重载)
# docker-compose.dev.yml
services:
  app:
    volumes:
      - .:/app              # 挂载源码
      - /app/node_modules   # 避免覆盖容器内的node_modules
    command: npm run dev
    environment:
      - NODE_ENV=development

# 启动不同环境
docker compose up -d                              # 默认(仅基础配置)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d  # 开发
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d # 生产

三、健康检查配置

healthcheck:
  test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
  interval: 30s      # 检查间隔
  timeout: 10s       # 超时时间
  retries: 3         # 失败重试次数
  start_period: 60s  # 启动初始化等待时间(容器启动后等待60s再开始检查)

四、数据持久化策略

# 命名卷(推荐:Docker管理,性能好)
volumes:
  db_data:
    driver: local

# 绑定挂载(开发时挂载源码,生产慎用)
volumes:
  - ./src:/app/src

# 只读挂载(配置文件等)
volumes:
  - ./nginx.conf:/etc/nginx/nginx.conf:ro  # ro = read only

五、网络配置与服务发现

networks:
  frontend:     # 前端网络(只有Nginx和App可以访问)
    driver: bridge
  backend:      # 后端网络(App和DB通信)
    driver: bridge

services:
  nginx:
    networks: [frontend]
  app:
    networks: [frontend, backend]  # 连接两个网络
  db:
    networks: [backend]  # 数据库只在后端网络,外部无法直接访问

六、资源限制配置

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'       # 最多使用1个CPU
          memory: 512M      # 内存上限512MB
        reservations:
          cpus: '0.25'      # 保留0.25个CPU
          memory: 128M      # 保留128MB内存

七、常用操作命令

docker compose up -d                    # 后台启动所有服务
docker compose down                     # 停止并删除容器
docker compose down -v                  # 停止并删除容器和卷(数据丢失!)
docker compose ps                       # 查看运行状态
docker compose logs -f app              # 实时查看服务日志
docker compose exec app bash            # 进入运行中的容器
docker compose pull                     # 更新所有服务镜像
docker compose restart app              # 重启特定服务
docker compose scale app=3              # 扩展服务实例数

八、总结

Docker Compose是开发和测试环境标准化的利器。通过docker-compose.yml将应用依赖的所有服务描述清楚,新成员clone代码后一条命令即可启动完整环境,彻底告别”环境配置半天,写代码五分钟”的窘境。生产环境建议升级到Docker Swarm或Kubernetes获得更完善的编排能力。