跳转到内容

Docker Compose 高级配置与多服务编排实战 2026 | 容器编排完全指南

Docker Compose 高级配置与多服务编排

Docker Compose 是定义和运行多容器 Docker 应用程序的工具。从简单的开发环境到复杂的生产部署,Compose 都能胜任。本文将深入 Compose 的高级特性,从环境变量管理到滚动更新,全面掌握容器编排技能。


一、Compose 文件结构

1.1 Compose 版本与基本结构

yaml
# docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "80:80"
    depends_on:
      - db
      - redis

  db:
    image: postgres:15
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

networks:
  default:
    name: my-network

1.2 常用配置项速查

配置项说明
image使用的镜像
build构建镜像的上下文
ports端口映射
volumes数据卷挂载
environment环境变量
env_file环境变量文件
depends_on服务依赖
networks网络配置
healthcheck健康检查
restart重启策略
deploy部署配置(Swarm)
command覆盖启动命令
entrypoint覆盖入口点

二、环境变量管理

2.1 多种环境变量方式

yaml
# 方式1:直接在 docker-compose.yml 中定义
services:
  web:
    image: nginx
    environment:
      - NODE_ENV=production
      - API_URL=https://api.example.com
      - DEBUG=false

# 方式2:键值对格式
services:
  web:
    image: nginx
    environment:
      NODE_ENV: production
      API_URL: https://api.example.com

2.2 使用 .env 文件

bash
# .env
NODE_ENV=production
API_URL=https://api.example.com
DB_PASSWORD=secret123
REDIS_URL=redis://redis:6379
yaml
# docker-compose.yml
services:
  web:
    image: myapp
    env_file:
      - .env

2.3 多环境配置

yaml
# docker-compose.base.yml - 基础配置
services:
  web:
    build: .
    volumes:
      - ./src:/app/src
yaml
# docker-compose.dev.yml - 开发环境
services:
  web:
    environment:
      - NODE_ENV=development
      - DEBUG=true
    ports:
      - "3000:3000"
    command: npm run dev

  db:
    image: postgres:15
    ports:
      - "5432:5432"
yaml
# docker-compose.prod.yml - 生产环境
services:
  web:
    environment:
      - NODE_ENV=production
    ports:
      - "80:3000"
    restart: always
    deploy:
      replicas: 3
bash
# 启动开发环境
docker-compose -f docker-compose.base.yml -f docker-compose.dev.yml up -d

# 启动生产环境
docker-compose -f docker-compose.base.yml -f docker-compose.prod.yml up -d

2.4 变量替换

yaml
services:
  web:
    image: myapp:${VERSION:-latest}
    ports:
      - "${WEB_PORT:-8080}:3000"
    environment:
      - DB_HOST=${DB_HOST:-db}

三、网络配置

3.1 自定义网络

yaml
services:
  frontend:
    image: nginx
    networks:
      - frontend
      - backend

  api:
    image: myapi
    networks:
      - backend
      - database

  db:
    image: postgres
    networks:
      - database

networks:
  frontend:
    name: frontend-net
    driver: bridge

  backend:
    name: backend-net
    driver: bridge

  database:
    name: database-net
    driver: bridge
    internal: true  # 内部网络,无法访问外网

3.2 网络别名

yaml
services:
  web:
    image: nginx
    networks:
      frontend:
        aliases:
          - webserver
          - nginx-server

  app:
    image: myapp
    networks:
      backend:
        aliases:
          - api-server

3.3 主机网络模式

yaml
services:
  monitoring:
    image: prom/prometheus
    network_mode: host  # 使用主机网络
    pid: host           # 使用主机 PID 命名空间

四、数据持久化

4.1 命名卷(推荐)

yaml
services:
  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
    name: postgres-data
    driver: local

  redis_data:
    name: redis-data
    driver: local

4.2 绑定挂载

yaml
services:
  web:
    image: nginx
    volumes:
      # 配置文件
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      # 静态文件
      - ./static:/usr/share/nginx/html:ro
      # 日志
      - ./logs:/var/log/nginx

  app:
    image: myapp
    volumes:
      # 源代码(开发用)
      - ./src:/app/src
      # 上传文件
      - ./uploads:/app/uploads

4.3 tmpfs(内存文件系统)

yaml
services:
  cache:
    image: redis:7
    tmpfs:
      - /tmp
      - /var/run

4.4 卷的备份与恢复

bash
# 备份数据卷
docker run --rm \
  -v postgres-data:/data \
  -v $(pwd)/backup:/backup \
  alpine tar czf /backup/postgres-backup.tar.gz /data

# 恢复数据卷
docker run --rm \
  -v postgres-data:/data \
  -v $(pwd)/backup:/backup \
  alpine tar xzf /backup/postgres-backup.tar.gz -C /

五、健康检查

5.1 HTTP 健康检查

yaml
services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

5.2 TCP 健康检查

yaml
services:
  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  redis:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

5.3 自定义健康检查脚本

yaml
services:
  app:
    build: .
    healthcheck:
      test: ["CMD-SHELL", "node /app/scripts/healthcheck.js"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
javascript
// scripts/healthcheck.js
const http = require('http')

const options = {
  hostname: 'localhost',
  port: 3000,
  path: '/health',
  method: 'GET'
}

const req = http.request(options, (res) => {
  process.exit(res.statusCode === 200 ? 0 : 1)
})

req.on('error', () => {
  process.exit(1)
})

req.end()

5.4 服务依赖与健康检查

yaml
services:
  web:
    image: myapp
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
      cache:
        condition: service_started

  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  redis:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      retries: 3

六、资源限制与性能调优

6.1 CPU 和内存限制

yaml
services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
        reservations:
          cpus: '1.0'
          memory: 512M

6.2 ulimit 调优

yaml
services:
  nginx:
    image: nginx
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
      nproc: 65535

6.3 重启策略

yaml
services:
  web:
    image: nginx
    restart: unless-stopped  # always | unless-stopped | on-failure | no

  worker:
    image: my-worker
    restart: on-failure:5  # 失败最多重启 5 次

七、多服务编排实战

7.1 完整 Web 应用栈

yaml
# docker-compose.yml
version: '3.8'

services:
  # Nginx 反向代理
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - ./logs/nginx:/var/log/nginx
    depends_on:
      - web
      - api
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - frontend
      - backend

  # 前端应用
  web:
    image: my-web-app:latest
    build:
      context: ./web
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
      - API_BASE_URL=https://api.example.com
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:3000"]
      interval: 30s
      retries: 3
    networks:
      - backend

  # API 服务
  api:
    image: my-api:latest
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=5432
      - REDIS_HOST=redis
      - JWT_SECRET=${JWT_SECRET}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:3001/health"]
      interval: 30s
      retries: 3
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
    networks:
      - backend
      - database

  # PostgreSQL 数据库
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres/init:/docker-entrypoint-initdb.d:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - database

  # Redis 缓存
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - database

volumes:
  postgres_data:
  redis_data:

networks:
  frontend:
    name: frontend-net
  backend:
    name: backend-net
  database:
    name: database-net
    internal: true

7.2 启动顺序与依赖管理

bash
# 查看服务启动顺序
docker-compose config --services

# 只启动某个服务及其依赖
docker-compose up -d web

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs -f web

# 重启某个服务
docker-compose restart api

# 缩容/扩容
docker-compose up -d --scale api=3

八、生产环境部署

8.1 滚动更新

yaml
services:
  web:
    image: myapp:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 1        # 每次更新 1 个
        delay: 10s             # 间隔时间
        failure_action: rollback  # 失败回滚
        monitor: 30s           # 监控时间
        max_failure_ratio: 0.3  # 最大失败率
      rollback_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
        reservations:
          cpus: '1.0'
          memory: 512M

8.2 零停机部署

bash
# 构建新版本镜像
docker build -t myapp:v2 .

# 更新镜像标签
docker tag myapp:v2 myapp:latest

# 触发滚动更新
docker-compose up -d --no-deps web

# 查看更新进度
docker-compose ps
docker-compose logs -f web

8.3 蓝绿部署

yaml
# docker-compose.blue.yml - 蓝色环境
services:
  web-blue:
    image: myapp:v1
    ports:
      - "8080:3000"
yaml
# docker-compose.green.yml - 绿色环境
services:
  web-green:
    image: myapp:v2
    ports:
      - "8081:3000"
bash
# 1. 部署绿色环境
docker-compose -f docker-compose.green.yml up -d

# 2. 验证绿色环境正常
curl http://localhost:8081/health

# 3. 切换流量(更新 Nginx 配置指向绿色环境)
# 4. 停止蓝色环境
docker-compose -f docker-compose.blue.yml down

九、常用命令与技巧

9.1 日常管理命令

bash
# 启动服务
docker-compose up -d
docker-compose up -d --build  # 构建后启动
docker-compose up -d --force-recreate  # 强制重建

# 停止服务
docker-compose stop
docker-compose down
docker-compose down -v  # 删除数据卷

# 查看状态
docker-compose ps
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=100

# 进入容器
docker-compose exec web bash
docker-compose exec db psql -U postgres

# 查看配置
docker-compose config
docker-compose config --services
docker-compose config --volumes

9.2 清理与维护

bash
# 删除未使用的镜像
docker image prune

# 删除未使用的容器
docker container prune

# 删除未使用的数据卷
docker volume prune

# 一键清理
docker system prune -a

# 查看磁盘使用
docker system df

9.3 调试技巧

bash
# 查看容器启动日志
docker-compose logs web --no-log-prefix

# 查看实时资源使用
docker stats

# 进入容器调试
docker-compose exec web sh

# 复制文件到容器
docker cp ./local-file.txt mycontainer:/app/

# 从容器复制文件
docker cp mycontainer:/app/file.txt ./local/

十、最佳实践

10.1 配置管理

  1. 使用多文件配置:基础配置 + 环境配置
  2. 敏感信息用 .env:不要提交到版本控制
  3. 使用变量替换:提高配置灵活性
  4. 配置文件分层:common / dev / staging / prod

10.2 安全建议

  1. 最小权限原则:容器以非 root 用户运行
  2. 只读文件系统read_only: true
  3. 不暴露不必要的端口:只暴露需要的端口
  4. 使用内部网络:数据库等放在内部网络

10.3 性能优化

  1. 合理设置资源限制:避免资源争抢
  2. 使用命名卷:性能优于绑定挂载
  3. 健康检查:及时发现故障
  4. 多副本部署:提高可用性

十一、总结

  • ✅ 掌握 Compose 文件结构与常用配置
  • ✅ 环境变量管理与多环境配置
  • ✅ 网络配置(自定义网络、别名、内部网络)
  • ✅ 数据持久化(命名卷、绑定挂载、备份恢复)
  • ✅ 健康检查与服务依赖
  • ✅ 资源限制与性能调优
  • ✅ 多服务编排实战(完整 Web 应用栈)
  • ✅ 生产环境部署(滚动更新、蓝绿部署)
  • ✅ 常用命令与调试技巧

Docker Compose 是容器编排的入门利器,掌握这些高级配置技巧,让你能够轻松管理复杂的多容器应用。


相关阅读: