Docker Compose 多服務架構設計與實踐
9 分鐘閱讀 1,050 字
Docker Compose 多服務架構設計與實踐
現代應用幾乎都由多個服務組成:Web 伺服器、資料庫、快取、訊息佇列……如何讓這些服務在開發環境中順暢協作,Docker Compose 提供了最直觀的解答。本文將從架構設計的角度,探討如何用 Docker Compose 搭建健壯的多服務環境。
為什麼選擇 Docker Compose
相較於手動管理多個 docker run 命令,Docker Compose 帶來幾個關鍵優勢:
- 宣告式配置:整個服務棧的定義都在一個 YAML 檔案中,版本可控
- 自動網路:同一 Compose 檔案中的服務自動加入同一網路,可用服務名互相解析
- 依賴管理:透過
depends_on控制啟動順序 - 環境隔離:不同專案使用獨立的網路命名空間
基礎架構範例
以一個典型的 Web 應用為例,包含 Nginx、Node.js API、PostgreSQL 和 Redis:
# docker-compose.yml
version: "3.9"
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- api
networks:
- frontend
api:
build:
context: ./api
dockerfile: Dockerfile
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://user:password@postgres:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
networks:
- frontend
- backend
volumes:
- ./api:/app
- /app/node_modules
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
- ./db/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --requirepass redispassword
volumes:
- redis_data:/data
networks:
- backend
networks:
frontend:
backend:
internal: true # 後端網路不對外暴露
volumes:
postgres_data:
redis_data:健康檢查與啟動依賴
depends_on 的 condition 選項是 Compose v3 的重要功能,讓你能確保服務在依賴真正就緒後才啟動:
depends_on:
postgres:
condition: service_healthy # 等待 healthcheck 通過
redis:
condition: service_started # 只等容器啟動
migrations:
condition: service_completed_successfully # 等待一次性任務完成搭配健康檢查,可以有效避免「資料庫還在初始化,API 就已經崩潰」的問題。
多環境配置策略
實務中通常需要區分開發、測試、正式環境。推薦使用 override 檔案模式:
docker-compose.yml # 基礎配置(共用部分)
docker-compose.dev.yml # 開發環境覆蓋
docker-compose.prod.yml # 正式環境覆蓋
docker-compose.test.yml # 測試環境覆蓋# docker-compose.dev.yml
services:
api:
command: npm run dev # 使用 nodemon 熱重載
environment:
- DEBUG=*
ports:
- "9229:9229" # Node.js 偵錯埠
postgres:
ports:
- "5432:5432" # 開發時開放埠,方便 GUI 工具連接啟動命令:
# 開發環境
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# 正式環境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d管理機密資訊
永遠不要把密碼硬寫在 docker-compose.yml 中。使用 .env 檔案或 Docker Secrets:
# .env
POSTGRES_PASSWORD=supersecretpassword
REDIS_PASSWORD=anotherpassword
JWT_SECRET=myjwtsecret# docker-compose.yml
services:
postgres:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}記得將 .env 加入 .gitignore,並提供 .env.example 範本給團隊成員。
資料持久化策略
volumes:
# 具名 Volume:由 Docker 管理,適合資料庫等需要持久化的資料
postgres_data:
driver: local
# Bind Mount:直接掛載主機目錄,適合開發時的程式碼熱重載
# - ./src:/app/src
# tmpfs:僅存記憶體,適合測試環境的暫存資料
# tmpfs: /tmp常用除錯命令
# 查看所有服務狀態
docker compose ps
# 即時查看日誌(多服務)
docker compose logs -f api postgres
# 在執行中的容器執行命令
docker compose exec api sh
docker compose exec postgres psql -U user -d mydb
# 重建特定服務映像
docker compose build --no-cache api
# 清理所有資源
docker compose down -v --remove-orphans效能調優
在開發環境中,Volume 掛載可能成為效能瓶頸(尤其在 macOS 上)。可以使用以下技巧:
services:
api:
volumes:
- ./src:/app/src:cached # 讀取優先,適合主機寫入、容器讀取
- /app/node_modules # 匿名 Volume,避免掛載 node_modules總結
Docker Compose 讓多服務架構的管理變得簡單可控。關鍵要點:善用健康檢查確保啟動順序、用 override 檔案分離環境配置、妥善管理機密資訊,以及設計合理的網路隔離策略。掌握這些技巧,能讓你的本地開發環境與正式環境保持高度一致性。
分享這篇文章