docker compose 設定檔
什麼是 docker-compose.yml
- 一個 YAML 檔,描述多個容器(服務)要怎麼建立、連線、掛載、環境變數與啟動順序。
- 指令以階層表示:頂層(
services,volumes,networks,secrets,configs,name,profiles…),以及每個 service 內的設定。 - Compose V2 指令是
docker compose ...(舊版docker-compose ...也常見)。 version:欄位已不必寫(保留相容性而已)。
最小可用範例(逐行註解)
# 專案名稱(可不寫;預設用資料夾名,也可用 -p 覆蓋)
name: myapp
services:
web: # 服務名稱(最後會變成容器名稱的一部分)
image: nginx:alpine # 用現成映像;或改用 build: 自行建置
ports:
- "8080:80" # 主機:容器;支援加協定/綁定IP,如 "127.0.0.1:8080:80/tcp"
volumes:
- ./public:/usr/share/nginx/html:ro # bind mount:把本機目錄掛進容器(唯讀)
depends_on:
- db # 先啟 db 再啟 web(不等於「準備就緒」,見下)
db:
image: postgres:16
environment: # 容器內環境變數
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes:
- db-data:/var/lib/postgresql/data # named volume:持久化資料
healthcheck: # 健康檢查,搭配 depends_on 的 condition 才能「等到健康」
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 10s
timeout: 3s
retries: 5
volumes:
db-data: {} # 宣告 named volume,使用預設 driver(local)
啟動:
docker compose up -d # 背景建立+啟動
docker compose logs -f db # 追 db 日誌
docker compose down -v # 停止並刪容器/網路/卷(含 volumes)
進階範例(自建映像、多階段 build、環境檔、profile)
name: shop
services:
api:
build: # 用 Dockerfile 建置映像
context: ./api # build context(Dockerfile 裡的 COPY 以此為根)
dockerfile: Dockerfile
target: runtime # 只建到多階段裡的 runtime 階段
args: # 建置期參數(ARG)
APP_ENV: production
env_file: # 從檔案讀環境變數(可多個;後者覆蓋前者)
- .env
- .env.production
environment:
DB_URL: postgres://app:secret@db:5432/appdb
TZ: Asia/Taipei
ports:
- "8000:8000"
depends_on:
db:
condition: service_healthy # 需 db 健康(前面的 healthcheck)才啟 api
restart: unless-stopped
profiles: ["api"] # 只在特定 profile 啟用:docker compose --profile api up
web:
image: nginx:alpine
volumes:
- ./web/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- static:/srv/static
depends_on: [api]
profiles: ["web"]
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "app", "-d", "appdb"]
interval: 5s
retries: 10
volumes:
db-data: {}
static: {}
# 用 profile 啟用部分服務
# docker compose --profile api --profile web up -d
常用「頂層」指令(keys)
name: 專案名(決定預設 network/容器命名前綴)。services: 所有服務的集合(最重要)。volumes: 宣告 named volumes,支援driver,driver_opts,external: true。networks: 自訂網路;支援driver(多半是 bridge)、ipam、external: true。secrets:(可選)把秘密檔以檔案方式掛給服務(非 Swarm 時,Compose 也會以檔案方式提供)。configs:(可選)類似 secrets,用於一般設定檔。profiles:(可選)定義 profile 名稱;服務也可用profiles:限制啟動條件。
服務內最常用指令(依主題分組)
建置/映像
image: 使用既有映像(如redis:7)。-
build: 自行建置映像;可寫成字串(context 路徑),或物件:context,dockerfile,target,args,ssh,cache_from,labels…
-
pull_policy:always/if_not_present/never(拉映像策略;新 Compose 支援)。
程式啟動
command: 覆寫映像預設 CMD(陣列或字串)。entrypoint: 覆寫映像 ENTRYPOINT。working_dir: 容器內工作目錄。env_file: 從檔案載入環境變數(.env也會自動被讀取供變數替換用)。environment: 以 key: value 或- KEY=VAL設定環境變數。restart:no(預設)/always/on-failure[:N]/unless-stopped。-
depends_on: 控制啟動順序;支援:- 短寫:
depends_on: [db](只保證順序) - 進階:
condition: service_started|service_healthy|service_completed_successfully
- 短寫:
注意:沒有 healthcheck 時,
depends_on不會「等到可連線」,只保證先後順序。
網路/埠
-
ports: 連接埠映射(短寫/長寫皆可)- 短寫例:
"8080:80"、"127.0.0.1:8080:80/tcp" - 長寫例:
expose: 只在同網路內曝光的容器埠(不對外映射)。 *networks: 指定要連到哪些自訂網路,或設定別名aliases。 *extra_hosts: 加入 hosts(如- "db.local:10.0.0.10")。 *dns,dns_search: 自訂 DNS。 - 短寫例:
檔案系統/資源
-
volumes: 掛載(長寫可指定型別/唯讀)- 短寫:
./data:/data:ro - 長寫:
tmpfs: 於容器建立 tmpfs(記憶體檔系統)掛載。 *read_only: 將整個容器檔系統設唯讀(例外目錄用 volume)。 *shm_size: 共享記憶體大小(常見於瀏覽器/DB)。 *devices: 映射主機裝置,如- /dev/ttyUSB0:/dev/ttyUSB0。 *gpus:all或指定數量(需 NVIDIA 環境)。 - 短寫:
健康/停止
-
healthcheck:test:["CMD", "..."]/["CMD-SHELL","..."]interval,timeout,retries,start_period,start_interval
-
stop_signal: 優雅停止所傳送的訊號(預設 SIGTERM)。 stop_grace_period: 等待時間,之後送 SIGKILL。
安全/權限
user: 指定使用者("1000:1000"或"appuser")。cap_add,cap_drop: Linux capabilities 控制。security_opt: AppArmor/SELinux 等設定。privileged:true讓容器有更高權限(慎用)。sysctls: 核心參數(如net.core.somaxconn: 1024)。ulimits: 開檔數、行程數限制。
標籤/日誌
labels: 加上中繼資料(可用於 Prometheus/Traefik 等)。-
logging:driver: 如json-file(預設)、local、syslog、gelf…options: 如max-size: "10m",max-file: "3"。
其他
tty:true配互動 TTY。stdin_open:true等同-i。container_name: 不建議在團隊/CI 使用(會破壞可移植性,易衝突)。profiles: 控制此服務隸屬哪些 profile(啟動時用--profile選)。extends: 從其他檔/服務繼承設定(需要注意合併規則)。configs,secrets: 以檔案方式掛載設定/秘密;可搭配file:或external: true。
Swarm 專用:
deploy(例如deploy.replicas,deploy.resources.limits…)在單機 Compose模式通常會被忽略;要彈性限制資源可改用 Docker run 風格的選項或直接在 orchestrator 層處理。
變數替換(.env)
- Compose 會讀取同資料夾的
.env檔,供 YAML 內以${VAR}使用,支援預設值:${VAR:-default}。 env_file:是把變數塞進容器;而.env是替換 compose 檔文字,兩者用途不同。
小陷阱與建議
depends_on不等於「可連線」:要「等到健康」請加healthcheck,並設定depends_on: condition: service_healthy。volumes(named)是持久化的;docker compose down -v才會刪掉。container_name容易在多環境衝突,能不寫就不寫。- 盡量用 長寫法(例如
volumes的物件語法、ports的物件語法)可讀性更好。 - Windows/WSL 路徑與權限需特別注意(尤其 bind mount)。