DevOps•
2025-06-16
•8 min
•alltools.one Team
YAMLDockerDocker ComposeDevOpsContainers
YAML 與 Docker Compose:設定模式與技巧
Docker Compose 使用 YAML 來定義多容器應用程式。結構良好的 docker-compose.yml 是順暢開發環境與花數小時除錯容器問題之間的差別。本指南涵蓋必要的模式和常見陷阱。
基本結構
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
pgdata:
環境變數
行內定義
services:
api:
environment:
NODE_ENV: production
PORT: "3000"
DEBUG: "false"
從檔案載入
services:
api:
env_file:
- .env
- .env.local # 覆寫 .env 中的值
變數替換
引用主機環境變數:
services:
api:
image: myapp:${TAG:-latest} # 預設為 "latest"
environment:
API_KEY: ${API_KEY} # 必填——若未設定則失敗
LOG_LEVEL: ${LOG_LEVEL:-info} # 預設為 "info"
網路
自訂網路
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
internal: true # 無外部存取
在同一網路上的服務可以透過服務名稱互相連線。db 服務只能從 api 存取,無法從 web 存取。
連接埠對映
ports:
- "8080:80" # 主機:容器
- "443:443"
- "127.0.0.1:3000:3000" # 僅綁定到 localhost
- "3000" # 隨機主機連接埠
磁碟區
具名磁碟區(持久化)
services:
db:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
driver: local
綁定掛載(開發用)
services:
api:
volumes:
- ./src:/app/src # 原始碼
- /app/node_modules # 匿名磁碟區(防止覆寫)
匿名磁碟區模式(/app/node_modules)可防止主機的綁定掛載覆寫容器中已安裝的依賴項。
健康檢查
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
api:
depends_on:
db:
condition: service_healthy
這確保 api 只在 db 通過健康檢查後才啟動——而不僅是容器啟動時。
擴充欄位(DRY 模式)
使用 x- 前綴的欄位搭配 YAML 錨點來減少重複:
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
x-env: &common-env
TZ: UTC
LOG_FORMAT: json
services:
api:
<<: *common
build: ./api
environment:
<<: *common-env
PORT: "3000"
worker:
<<: *common
build: ./worker
environment:
<<: *common-env
QUEUE: default
更多關於 YAML 錨點的資訊,請參閱我們的 YAML 錨點與別名指南。
多階段 Compose
開發環境 vs 正式環境
# docker-compose.yml(基礎)
services:
api:
build: ./api
environment:
DATABASE_URL: postgres://db:5432/myapp
# docker-compose.override.yml(開發環境——自動載入)
services:
api:
volumes:
- ./api/src:/app/src
environment:
NODE_ENV: development
DEBUG: "true"
ports:
- "3000:3000"
- "9229:9229" # 除錯連接埠
# docker-compose.prod.yml
services:
api:
environment:
NODE_ENV: production
deploy:
replicas: 3
# 開發環境(自動載入 override)
docker compose up
# 正式環境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
常見陷阱
1. 未加引號的連接埠號
# 風險——YAML 會將 80:80 解讀為六十進位數字
ports:
- 80:80
# 安全——總是加引號
ports:
- "80:80"
2. 布林值的環境變數
# 錯誤——YAML 會轉換為布林值
environment:
DEBUG: true # 變成 Python True,而非字串 "true"
# 正確——所有環境變數值都加引號
environment:
DEBUG: "true"
3. depends_on 的時機問題
depends_on 只會等待容器啟動,而非就緒狀態:
# 容器啟動了,但資料庫可能尚未就緒
depends_on:
- db
# 等待健康檢查通過
depends_on:
db:
condition: service_healthy
使用我們的 YAML 驗證器來驗證你的 Docker Compose 檔案。
常見問題
docker-compose.yml 和 compose.yml 有什麼區別?
兩個檔案名稱都可以使用。compose.yml 是 Docker 推薦的新慣例。docker-compose.yml 是舊名稱。Docker Compose v2+ 會尋找這兩個檔案,若兩者都存在則優先使用 compose.yml。新專案建議使用 compose.yml。
Docker Compose 適合用在正式環境嗎?
Docker Compose 非常適合開發和簡單的部署。對於大規模正式環境,請考慮使用 Docker Swarm(原生支援 Compose 檔案)或 Kubernetes。Compose 的優勢在於你的開發設定可以直接作為正式環境的參考,減少環境差異。
相關資源
- YAML 驗證器 — 驗證 Docker Compose YAML
- YAML 錨點與別名 — DRY 設定模式
- YAML 語法教學 — YAML 基礎知識