docker-compose.yml 寫法
Compose 設定檔是一份 YAML 格式的文字檔,用來描述一組容器要怎麼建立、怎麼連線、資料放在哪裡。新版建議的檔名是 compose.yaml,舊的 docker-compose.yml 也一樣能用。本頁是設定檔的查詢手冊:先看整體結構,再依用途查詢服務裡常用的設定。還沒用過 Compose 的話,建議先讀 Docker Compose 的動手做範例。
先看懂 YAML 的寫法
YAML 用縮排表示層級,用冒號表示「名稱: 值」,用減號表示清單中的一項:
縮排只能用空白鍵
YAML 不能用 Tab 縮排,而且同一層的縮排格數必須一致(通常是兩格)。縮排錯誤是最常見的設定檔問題。
整體結構
name: myapp # 專案名稱(可省略,預設是資料夾名稱)
services: # 所有服務,最重要的部分
web:
...
db:
...
volumes: # 宣告要用的 Volume
db-data:
networks: # 宣告自訂網路(通常不需要,Compose 會自動建立)
backend:
舊教學常在第一行寫 version: "3.8",新版 Compose 已經不需要這一行了。
一份完整的範例
網站、API、資料庫三個服務,涵蓋最常用的設定:
services:
web:
image: nginx:1.28-alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
depends_on:
- api
api:
build: ./api
environment:
DB_HOST: db
DB_PASSWORD: ${DB_PASSWORD}
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 10
volumes:
db-data:
${DB_PASSWORD} 會從同資料夾的 .env 檔讀取,密碼就不用寫在設定檔裡。
服務裡常用的設定
用哪個 Image
| 設定 | 說明 | 範例 |
|---|---|---|
image |
使用現成的 Image | image: redis:8 |
build |
用 Dockerfile 自己建置 | build: . 或 build: ./api |
build 也可以寫得更詳細:
build:
context: ./api # Dockerfile 所在的資料夾
dockerfile: Dockerfile.prod
args: # 傳給 Dockerfile 裡 ARG 的值
APP_ENV: production
連接埠與網路
| 設定 | 說明 | 範例 |
|---|---|---|
ports |
把容器的連接埠開放給電腦 | - "8080:80" |
expose |
只讓同一個專案的其他容器連(不對外) | - "3000" |
networks |
接到指定的網路 | - backend |
ports 寫 "127.0.0.1:8080:80" 可以限制只有本機能連,資料庫這類服務建議這樣寫,或乾脆不開放。
資料保存
volumes:
- db-data:/var/lib/postgresql/data # Volume:名稱:容器路徑
- ./html:/usr/share/nginx/html:ro # Bind mount:電腦路徑:容器路徑,ro 代表唯讀
用到的 Volume 名稱,要在檔案最下方的 volumes: 宣告。兩者的差別請看 Docker 基本操作。
環境變數
啟動與重啟
| 設定 | 說明 |
|---|---|
command |
取代 Image 預設的啟動指令(Dockerfile 的 CMD) |
depends_on |
啟動順序;搭配 condition: service_healthy 可等對方準備好 |
restart |
當機或重開機後是否自動啟動:no(預設)、always、on-failure、unless-stopped |
healthcheck |
定期檢查服務是否正常 |
healthcheck 的寫法:
healthcheck:
test: ["CMD", "redis-cli", "ping"] # 檢查用的指令,要在 Image 裡存在
interval: 10s # 多久檢查一次
timeout: 3s # 多久沒回應算失敗
retries: 5 # 連續失敗幾次算不健康
start_period: 10s # 剛啟動時的緩衝時間
資源限制
其他
| 設定 | 說明 |
|---|---|
user |
用指定的使用者執行,例如 "1000:1000" |
working_dir |
容器裡的工作資料夾 |
profiles |
只在指定 profile 時才啟動,例如 profiles: ["debug"],用 docker compose --profile debug up 啟動 |
container_name |
固定容器名稱。不建議使用,同一台電腦跑兩份專案時會衝突 |
常見錯誤
- 縮排錯誤或用了 Tab:執行
docker compose config可以檢查設定檔格式。 depends_on只寫服務名稱:只保證啟動順序,不保證對方已經可以連線。依賴資料庫時請加上condition: service_healthy。- 在容器裡用
localhost連其他服務:要用服務名稱,例如db。 - 以為
.env會自動傳進容器:.env只替換設定檔裡的${...},要傳進容器請寫environment或env_file。 - 執行
down -v刪掉了資料:-v會刪除 Volume,資料庫資料會一起消失。
參考資料
推薦影音
Multi-container applications
簡述:Docker 官方短片,比較一個一個用 docker run 啟動和用 Compose 設定檔管理的差別。(Docker 官方)
Docker Compose will BLOW your MIND!! (a tutorial)
簡述:從一行 docker run 改寫成 Compose 設定檔,再一步步加入更多服務,看懂設定檔每個欄位的作用。(NetworkChuck)
更多影片請見 影音教學。