前言
在現代軟體開發流程中,我們經常需要在不同環境(開發、測試、生產)之間切換。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 工作流程更加順暢高效。建議從小規模專案開始實踐,逐步建立適合團隊的最佳實務。
參考資源