Skip to content

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)、ipamexternal: 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"
    • 長寫例:

    ports:
      - target: 80
        published: 8080
        protocol: tcp
        mode: host
    
    * expose: 只在同網路內曝光的容器埠(不對外映射)。 * networks: 指定要連到哪些自訂網路,或設定別名 aliases。 * extra_hosts: 加入 hosts(如 - "db.local:10.0.0.10")。 * dns, dns_search: 自訂 DNS。

檔案系統/資源

  • volumes: 掛載(長寫可指定型別/唯讀)

    • 短寫:./data:/data:ro
    • 長寫:

    volumes:
      - type: bind
        source: ./data
        target: /data
        read_only: true
    
    * 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(預設)、localsysloggelf
    • 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)。

常用指令彙整

docker compose up -d                 # 建好 + 背景啟動
docker compose up -d --build         # 同時重建映像
docker compose ps                    # 看狀態
docker compose logs -f api           # 追某服務日誌
docker compose restart web           # 重啟服務
docker compose stop                  # 停止但保留資源
docker compose down                  # 停止並移除網路/容器
docker compose down -v               # 連 volumes 一起清