為開發和生產設計可重複使用的 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 Swarm 和 Compose 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、用於特定於環境的設定的 覆蓋檔案、用於條件服務的 設定檔,以及用於機密和配置的 環境變數。
這種分層方法消除了重複,減少了配置偏差,並使您的部署管道在開發、登台和生產過程中可預測。採用這些模式可以充滿信心地出貨。

