正在加载,请稍候…

Docker Compose 生产环境部署:多服务应用、密钥管理与健康检查

在生产环境中使用 Docker Compose 构建多服务架构,涵盖 Compose Watch、密钥管理、健康检查、资源限制及 Docker Swarm 部署

Docker Compose 生产环境部署:多服务应用、密钥管理与健康检查

Docker Compose 超越开发环境

Docker Compose 已演变为生产就绪工具,支持 Compose Watch、部署配置和内置密钥管理。

Docker Compose 生产环境部署:多服务应用、密钥管理与健康检查 示意图

生产环境 Compose 文件

# compose.yml
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    image: myapp/api:latest
    restart: unless-stopped
    environment:
      NODE_ENV: production
      DATABASE_URL: postgresql://db:5432/myapp
    secrets:
      - jwt_secret
      - db_password
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - backend

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myapp"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G
    networks:
      - backend

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

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - api
    networks:
      - backend
      - frontend

secrets:
  jwt_secret:
    file: ./secrets/jwt_secret.txt  # 或使用 Docker Swarm 密钥
  db_password:
    file: ./secrets/db_password.txt

volumes:
  postgres_data:
  redis_data:

networks:
  backend:
    driver: bridge
  frontend:
    driver: bridge

Docker Compose 生产环境部署:多服务应用、密钥管理与健康检查 示意图

多阶段 Dockerfile

# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 开发阶段  
FROM builder AS development
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

# 生产阶段
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup --system app && adduser --system --group app
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=app:app . .
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s CMD curl -f http://localhost:3000/health
CMD ["node", "dist/server.js"]

Docker Compose 生产环境部署:多服务应用、密钥管理与健康检查 示意图

Compose Watch(开发环境热重载)

services:
  api:
    build: .
    develop:
      watch:
        - path: ./src
          action: sync            # 同步文件,无需重建
          target: /app/src
        - path: ./package.json
          action: rebuild         # 包变化时完全重建
        - path: ./Dockerfile
          action: rebuild
docker compose watch

部署到 Docker Swarm

docker swarm init

# 创建密钥
echo "my-jwt-secret" | docker secret create jwt_secret -
echo "my-db-password" | docker secret create db_password -

# 部署堆栈
docker stack deploy -c compose.yml myapp

# 扩展服务
docker service scale myapp_api=5

# 滚动更新
docker service update --image myapp/api:v2 myapp_api

# 查看日志
docker service logs myapp_api --follow

资源监控

# 查看资源使用情况
docker stats $(docker compose ps -q)

# 清理未使用的资源
docker system prune -a --volumes