Docker Compose Profiles 環境切換

Docker Compose Profiles Environment Switching

前言

在現代軟體開發流程中,我們經常需要在不同環境(開發、測試、生產)之間切換。Docker Compose Profiles 是一個強大的功能,能讓我們在單一 docker-compose.yml 檔案中定義多種服務組合,並根據需求選擇性地啟動特定服務。本文將深入探討 Profiles 的各種使用方式與最佳實務。

1. Profiles 功能介紹

Docker Compose Profiles 於 Docker Compose v1.28.0 版本引入,主要用於解決以下問題:

  • 環境隔離:區分開發、測試、生產環境所需的服務
  • 選擇性啟動:僅啟動當前任務所需的服務,節省系統資源
  • 配置簡化:避免維護多個 compose 檔案,減少配置重複

核心概念

Profiles 允許您為服務指定一個或多個標籤(profile),只有在明確啟用該 profile 時,對應的服務才會啟動。未指定任何 profile 的服務會在所有情況下啟動。

2. 基本語法與設定

基本語法

在服務定義中使用 profiles 關鍵字來指定服務所屬的 profile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3.9"

services:
  # 預設服務 - 始終啟動
  web:
    image: nginx:alpine
    ports:
      - "80:80"

  # 僅在 debug profile 啟用時啟動
  debugger:
    image: busybox
    profiles:
      - debug
    command: sleep infinity

  # 僅在 dev profile 啟用時啟動
  adminer:
    image: adminer
    profiles:
      - dev
    ports:
      - "8080:8080"

多重 Profile 指派

一個服務可以同時屬於多個 profiles:

1
2
3
4
5
6
7
8
9
services:
  monitoring:
    image: prom/prometheus
    profiles:
      - dev
      - staging
      - production
    ports:
      - "9090:9090"

3. 多環境配置範例

以下是一個完整的多環境配置範例,展示如何為不同環境設定不同的服務組合:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
version: "3.9"

services:
  # ===== 核心服務(始終啟動)=====
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=${NODE_ENV:-development}
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

  # ===== 開發環境服務 =====
  adminer:
    image: adminer
    profiles:
      - dev
    ports:
      - "8080:8080"
    depends_on:
      - db

  mailhog:
    image: mailhog/mailhog
    profiles:
      - dev
    ports:
      - "1025:1025"
      - "8025:8025"

  # ===== 測試環境服務 =====
  selenium:
    image: selenium/standalone-chrome
    profiles:
      - test
    ports:
      - "4444:4444"
    shm_size: 2gb

  test-runner:
    build:
      context: .
      dockerfile: Dockerfile.test
    profiles:
      - test
    depends_on:
      - app
      - selenium

  # ===== 監控服務 =====
  prometheus:
    image: prom/prometheus
    profiles:
      - monitoring
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    profiles:
      - monitoring
    ports:
      - "3001:3000"
    depends_on:
      - prometheus

  # ===== 除錯工具 =====
  pgadmin:
    image: dpage/pgadmin4
    profiles:
      - debug
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@admin.com
      PGADMIN_DEFAULT_PASSWORD: admin
    ports:
      - "5050:80"

volumes:
  postgres_data:

4. 服務依賴與 Profiles

depends_on 與 Profiles 的互動

當服務 A 依賴服務 B,且服務 B 有指定 profile 時,需要特別注意:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
services:
  web:
    image: nginx
    depends_on:
      - api

  api:
    image: myapi
    profiles:
      - backend
    depends_on:
      - db

  db:
    image: postgres
    profiles:
      - backend

在上述配置中,如果直接執行 docker compose up web,將會失敗,因為 api 服務需要 backend profile 才能啟動。正確的做法是:

1
docker compose --profile backend up web

自動依賴解析

Docker Compose 會自動啟動依賴服務,但前提是該依賴服務的 profile 必須被啟用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
services:
  frontend:
    image: frontend-app
    depends_on:
      - backend

  backend:
    image: backend-api
    profiles:
      - api
    depends_on:
      - database

  database:
    image: postgres
    profiles:
      - api

執行 docker compose --profile api up frontend 會啟動所有三個服務。

5. CLI 使用方法

啟用單一 Profile

1
2
3
4
5
# 使用 --profile 旗標
docker compose --profile dev up

# 使用環境變數
COMPOSE_PROFILES=dev docker compose up

啟用多個 Profiles

1
2
3
4
5
# 多次使用 --profile 旗標
docker compose --profile dev --profile debug up

# 使用逗號分隔的環境變數
COMPOSE_PROFILES=dev,debug docker compose up

常用指令範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 啟動開發環境
docker compose --profile dev up -d

# 啟動開發環境並進行建置
docker compose --profile dev up -d --build

# 查看特定 profile 的服務狀態
docker compose --profile dev ps

# 停止特定 profile 的服務
docker compose --profile dev down

# 查看特定 profile 的日誌
docker compose --profile dev logs -f

# 在啟用 profile 的情況下執行一次性命令
docker compose --profile test run --rm test-runner npm test

列出所有服務(包含未啟用的 profile)

1
docker compose config --services

6. 與 Override 檔案整合

Profiles 可以與 Docker Compose 的 override 機制完美配合使用:

基礎配置 (docker-compose.yml)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: "3.9"

services:
  app:
    image: myapp:latest
    ports:
      - "3000:3000"

  db:
    image: postgres:15
    profiles:
      - database

開發環境覆寫 (docker-compose.override.yml)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3.9"

services:
  app:
    build: .
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - DEBUG=true

  db:
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: devpassword

  adminer:
    image: adminer
    profiles:
      - dev
    ports:
      - "8080:8080"

生產環境配置 (docker-compose.prod.yml)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.9"

services:
  app:
    image: myapp:${VERSION:-latest}
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    environment:
      - NODE_ENV=production

  db:
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_prod_data:/var/lib/postgresql/data

volumes:
  postgres_prod_data:

使用多個配置檔案

1
2
3
4
5
# 開發環境(自動載入 docker-compose.override.yml)
docker compose --profile dev --profile database up

# 生產環境
docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile database up -d

7. 實際應用場景

場景一:微服務開發

在微服務架構中,開發人員可能只需要啟動部分服務:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
version: "3.9"

services:
  gateway:
    image: api-gateway
    ports:
      - "8000:8000"

  user-service:
    image: user-service
    profiles:
      - users
      - full

  order-service:
    image: order-service
    profiles:
      - orders
      - full

  payment-service:
    image: payment-service
    profiles:
      - payments
      - full

  notification-service:
    image: notification-service
    profiles:
      - notifications
      - full
1
2
3
4
5
6
7
8
# 只開發用戶服務
docker compose --profile users up

# 開發訂單和支付服務
docker compose --profile orders --profile payments up

# 啟動所有服務
docker compose --profile full up

場景二:CI/CD 管線

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
version: "3.9"

services:
  app:
    build: .

  # 單元測試
  unit-tests:
    build:
      context: .
      target: test
    profiles:
      - unit-test
    command: npm run test:unit

  # 整合測試
  integration-tests:
    build:
      context: .
      target: test
    profiles:
      - integration-test
    depends_on:
      - db
      - redis
    command: npm run test:integration

  # E2E 測試
  e2e-tests:
    build:
      context: .
      target: test
    profiles:
      - e2e-test
    depends_on:
      - app
      - selenium
    command: npm run test:e2e

  selenium:
    image: selenium/standalone-chrome
    profiles:
      - e2e-test

  db:
    image: postgres:15
    profiles:
      - integration-test
      - e2e-test

  redis:
    image: redis:alpine
    profiles:
      - integration-test
      - e2e-test
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# CI 管線中的使用
# Stage 1: 單元測試
docker compose --profile unit-test run --rm unit-tests

# Stage 2: 整合測試
docker compose --profile integration-test run --rm integration-tests

# Stage 3: E2E 測試
docker compose --profile e2e-test up -d app selenium
docker compose --profile e2e-test run --rm e2e-tests

場景三:本地開發工具

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
version: "3.9"

services:
  app:
    build: .
    ports:
      - "3000:3000"

  # 資料庫管理工具
  phpmyadmin:
    image: phpmyadmin
    profiles:
      - tools
    ports:
      - "8081:80"

  # Redis 管理介面
  redis-commander:
    image: rediscommander/redis-commander
    profiles:
      - tools
    ports:
      - "8082:8081"

  # 日誌聚合
  loki:
    image: grafana/loki
    profiles:
      - logging
    ports:
      - "3100:3100"

  # 效能分析
  jaeger:
    image: jaegertracing/all-in-one
    profiles:
      - tracing
    ports:
      - "16686:16686"

8. 最佳實務

8.1 命名規範

使用清晰、一致的 profile 命名:

1
2
3
4
5
6
7
8
9
# 推薦的命名方式
profiles:
  - dev          # 開發環境
  - test         # 測試環境
  - staging      # 預備環境
  - prod         # 生產環境
  - debug        # 除錯工具
  - monitoring   # 監控服務
  - tools        # 開發工具

8.2 預設服務設計

將核心服務設為預設(不指定 profile),輔助服務才使用 profiles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
services:
  # 核心服務 - 無 profile,始終啟動
  app:
    image: myapp

  db:
    image: postgres

  # 輔助服務 - 使用 profile
  adminer:
    profiles:
      - dev

8.3 使用環境變數檔案

結合 .env 檔案管理 profile:

1
2
3
4
5
6
7
8
# .env.dev
COMPOSE_PROFILES=dev,debug

# .env.test
COMPOSE_PROFILES=test

# .env.prod
COMPOSE_PROFILES=prod,monitoring
1
2
# 使用特定環境的配置
docker compose --env-file .env.dev up

8.4 文件化 Profile 用途

在 compose 檔案中加入註解說明各 profile 的用途:

1
2
3
4
5
6
7
8
# Profiles 說明:
# - dev: 開發環境工具(adminer, mailhog)
# - test: 測試環境(selenium, test-runner)
# - debug: 除錯工具(pgadmin, redis-commander)
# - monitoring: 監控堆疊(prometheus, grafana)

services:
  # ...

8.5 避免過度使用

不要為每個服務都建立獨立的 profile,這會增加複雜度:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 不建議
services:
  service-a:
    profiles: [service-a]
  service-b:
    profiles: [service-b]
  service-c:
    profiles: [service-c]

# 建議:按功能或環境分組
services:
  service-a:
    profiles: [backend]
  service-b:
    profiles: [backend]
  service-c:
    profiles: [frontend]

8.6 結合 Makefile 簡化操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.PHONY: dev test prod

dev:
	docker compose --profile dev up -d

dev-logs:
	docker compose --profile dev logs -f

test:
	docker compose --profile test run --rm test-runner

prod:
	docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

clean:
	docker compose --profile dev --profile test --profile debug down -v

總結

Docker Compose Profiles 是管理多環境容器配置的強大工具。透過合理規劃 profiles,可以:

  • 簡化開發流程,快速切換不同環境
  • 減少資源消耗,僅啟動必要的服務
  • 統一配置管理,避免維護多個 compose 檔案
  • 提升團隊協作效率,標準化開發環境

掌握 Profiles 的使用技巧,將能讓您的 Docker 工作流程更加順暢高效。建議從小規模專案開始實踐,逐步建立適合團隊的最佳實務。

參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy