Featured image of post 為開發和生產設計可重複使用的 Docker Compose 配置Featured image of post 為開發和生產設計可重複使用的 Docker Compose 配置

為開發和生產設計可重複使用的 Docker Compose 配置

透過連結配置覆蓋、管理連接埠、磁碟區共用和環境檔案來維護乾燥的撰寫檔案。

為開發和生產設計可重複使用的 Docker Compose 配置

Docker Compose 是用於定義和運行多容器應用程式的標準工具。但許多團隊去年陷入了為開發、登台和生產維護單獨的 docker-compose.yml 文件的陷阱 - 導致重複、漂移和配置錯誤。

更好的方法使用組合文件覆蓋配置文件環境變數來保持適應每個環境的單一事實來源。


基本 compose.yml 模式

從定義共享服務定義的單一 compose.yml 開始 - 在不同環境中保持不變的映像、命令、連接埠和環境。

# compose.yml
services:
  app:
    image: myapp:${APP_VERSION:-latest}
    build:
      context: .
      target: ${BUILD_TARGET:-development}
    ports:
      - "${APP_PORT:-3000}:3000"
    environment:
      - NODE_ENV=${NODE_ENV:-development}
      - DATABASE_URL=${DATABASE_URL}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pgdata:

使用具有預設值 (${VAR:-default}) 的環境變數來保持基本檔案的通用性。


使用 compose.override.yml 覆寫環境

Docker Compose 會自動讀取 compose.override.yml(如果存在)。將此用於僅開發設定 - 切勿提交會影響生產的覆蓋。

# compose.override.yml (excluded from production deployments)
services:
  app:
    build:
      target: development
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "9229:9229" # debugger
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    command: npm run dev

  db:
    ports:
      - "5432:5432" # expose for local tools
    volumes:
      - ./scripts/seed:/docker-entrypoint-initdb.d

對於生產,請使用單獨的覆蓋檔案:

# compose.prod.yml
services:
  app:
    build:
      target: production
    restart: always
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

部署方式:docker compose -f compose.yml -f compose.prod.yml up -d


使用環境變體的配置文件

設定檔 (Docker Compose 2.0+) 讓您可以根據環境有條件地啟用服務。

services:
  mailhog:
    image: mailhog/mailhog
    profiles: ["development", "staging"]
    ports:
      - "8025:8025"

  redis:
    image: redis:7-alpine
    profiles: ["development", "staging", "production"]

  redis-commander:
    image: rediscommander/redis-commander
    profiles: ["development"]
    ports:
      - "8081:8081"

執行 docker compose --profile development up 以僅啟動與開發相關的服務。


健康檢查和重啟策略

始終為支持它們的每項服務定義健康檢查。結合重啟策略進行自我修復部署。

services:
  app:
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 40s

  worker:
    restart: on-failure:5
    depends_on:
      app:
        condition: service_healthy

depends_on.condition: service_healthy 確保工作執行緒僅在應用程式通過健康檢查後啟動。


資源限制和擴展

透過設定資源限制來防止失控的容器導致主機崩潰。

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M

  worker:
    deploy:
      mode: replicated
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 1G

注意:deploy 設定適用於 Docker SwarmCompose v3 堆疊。對於普通 docker compose,請使用 --compatibility 標誌或特定於平台的限制。


保密管理

切勿在撰寫文件中對機密進行硬編碼。使用具有受限權限的 Docker 機密或環境檔案。

# Using Docker secrets (Swarm mode)
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  app:
    secrets:
      - db_password
    environment:
      - DATABASE_URL=postgres://user:${DB_PASSWORD}@db:5432/myapp

對於非 Swarm 設置,請使用 .env 檔案:

# .env (never committed to version control)
DB_USER=myapp
DB_PASS=s3cret!
DB_NAME=myapp
APP_PORT=3000

日誌記錄配置

集中日誌記錄可防止容器日誌垃圾郵件填滿您的磁碟。

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

  # Production logging to a remote service
  log-collector:
    logging:
      driver: "fluentd"
      options:
        fluentd-address: "localhost:24224"
        tag: "docker.{{.Name}}"

結論

設計可重複使用的 Docker Compose 配置涉及關注點分離:用於共享定義的 基本 compose.yml、用於特定於環境的設定的 覆蓋檔案、用於條件服務的 設定檔,以及用於機密和配置的 環境變數

這種分層方法消除了重複,減少了配置偏差,並使您的部署管道在開發、登台和生產過程中可預測。採用這些模式可以充滿信心地出貨。