Docker Compose 从入门到生产:多容器应用编排实战


阿里云特惠 - 新用户专享

Docker Compose 从入门到生产:多容器应用编排实战

单容器只能解决单个服务的问题,实际应用往往需要 Web + App + Database + Cache 多个服务协同工作。Docker Compose 用一个 YAML 文件定义和管理多容器应用,是开发和中小规模生产部署的利器。本文从基础语法到生产实践,全面讲解 Docker Compose 的使用。

一、Docker Compose 安装

# Docker Desktop 已内置(Windows/Mac)
# Linux 独立安装(推荐 v2 版本,命令为 docker compose 而非 docker-compose)
sudo apt install docker-compose-plugin

# 验证
docker compose version

二、compose.yaml 结构详解

# compose.yaml(新版推荐命名,旧版为 docker-compose.yml)

version: '3.9'  # 指定 Compose 文件格式版本

services:
  # Web 前端(Nginx)
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro    # 只读挂载配置
      - ./certbot/www:/var/www/certbot:ro       # Let's Encrypt 验证
      - ./certbot/conf:/etc/letsencrypt:ro      # SSL 证书
    depends_on:
      app:
        condition: service_healthy              # 等待 app 健康检查通过后再启动
    restart: unless-stopped                    # 非手动停止则自动重启

  # 后端应用(Node.js)
  app:
    build:
      context: .                               # Dockerfile 所在目录
      dockerfile: Dockerfile
      target: production                       # 多阶段构建的目标阶段
    environment:
      - NODE_ENV=production
      - DB_HOST=db                             # 用 service 名称替代 IP
      - DB_PORT=3306
      - DB_NAME=myapp
      - DB_PASS=${DB_PASSWORD}                 # 从 .env 文件或环境变量读取
      - REDIS_URL=redis://cache:6379
    secrets:
      - db_password                            # Docker Secrets 管理敏感信息
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped

  # MySQL 数据库
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql               # 命名卷持久化数据
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro  # 初始化 SQL
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      retries: 5
    restart: unless-stopped

  # Redis 缓存
  cache:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 512mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  db_data:      # 数据库数据卷(默认 local driver,数据存在 Docker 管理目录)
  redis_data:

secrets:
  db_password:
    environment: DB_PASSWORD  # 从环境变量创建 Secret

三、.env 文件管理环境变量

# .env(此文件不要提交到 Git!加入 .gitignore)
MYSQL_ROOT_PASSWORD=MyRootPass@2026
DB_PASSWORD=MyAppPass@2026
REDIS_PASSWORD=MyRedisPass@2026

# .env.example(提交到 Git,作为模板)
MYSQL_ROOT_PASSWORD=your_root_password_here
DB_PASSWORD=your_app_password_here
REDIS_PASSWORD=your_redis_password_here

四、常用 Compose 命令

docker compose up -d              # 后台启动所有服务
docker compose up --build -d      # 重新构建镜像后启动
docker compose down               # 停止并删除容器(保留数据卷)
docker compose down -v            # 停止并删除容器 + 数据卷(谨慎!会删数据)

docker compose ps                 # 查看服务状态
docker compose logs -f app        # 实时查看 app 服务日志
docker compose exec app bash      # 进入 app 容器
docker compose restart app        # 重启 app 服务(不重建)

# 只更新 app 服务(不重启其他服务)
docker compose up -d --no-deps --build app

docker compose pull               # 拉取最新镜像
docker compose config             # 验证并输出最终配置(调试用)

五、多环境配置(dev/staging/prod)

# 文件结构
compose.yaml          # 公共基础配置
compose.dev.yaml      # 开发环境覆盖
compose.prod.yaml     # 生产环境覆盖

# compose.dev.yaml(开发环境:挂载源码、开 debug 模式)
services:
  app:
    volumes:
      - .:/app           # 挂载源码,实时生效
    environment:
      - NODE_ENV=development
      - DEBUG=*
    ports:
      - "9229:9229"      # Node.js 调试端口

# 使用多文件启动
docker compose -f compose.yaml -f compose.dev.yaml up -d

六、健康检查与服务依赖

depends_on 默认只等待容器启动,不等待服务就绪。使用 condition: service_healthy + healthcheck 才能确保数据库真正可用后再启动应用:

  db:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s   # 容器启动后30秒内的失败不计入重试

七、生产环境注意事项

  • 不要用 latest 标签:指定精确版本(如 mysql:8.0.36),避免意外升级
  • 日志驱动:配置 logging.options.max-size 防止日志文件撑爆磁盘
  • 资源限制:为每个服务配置 deploy.resources.limits(CPU/内存上限)
  • 数据卷备份:定期备份 db_data 卷,不能依赖容器本身

总结

Docker Compose 是中小项目容器化部署的首选方案。它简单直观,一个 YAML 文件描述整个应用栈,几条命令完成部署。掌握多文件多环境配置、健康检查依赖、.env 环境变量管理,你的 Compose 使用就能从”能跑”升级为”生产可用”。

发表评论