使用 Compose Watch

要求: Docker Compose 2.22.0 或更高版本

watch 屬性可以在您編輯並儲存程式碼時,自動更新並預覽執行中的 Compose 服務。對於許多專案來說,一旦 Compose 啟動後,這能實現無需手動操作的開發工作流程,因為服務會在您儲存工作時自動更新。

watch 遵循以下檔案路徑規則:

  • 除了忽略檔案的樣式外,所有路徑均相對於專案目錄。
  • 目錄會被遞迴監控。
  • 不支援萬用字元 (Glob patterns)。
  • .dockerignore 中的規則同樣適用。
    • 使用 ignore 選項可定義需要忽略的其他路徑(語法相同)。
    • 常見 IDE(如 Vim、Emacs、JetBrains 等)的暫存檔/備份檔會被自動忽略。
    • .git 目錄會被自動忽略。

您不需要為 Compose 專案中的所有服務開啟 watch。在某些情況下,可能只有專案的一部分(例如 Javascript 前端)適合自動更新。

Compose Watch 專為使用 build 屬性從本地原始碼建構的服務而設計。它不會追蹤依賴於 image 屬性指定的預建映像檔的服務變更。

Compose Watch 與綁定掛載 (bind mounts) 的比較

Compose 支援將主機目錄共享到服務容器內部。Watch 模式並未取代此功能,而是作為專門適合容器開發的輔助工具存在。

更重要的是,watch 提供了比綁定掛載更細緻的控制。Watch 規則讓您可以忽略監控樹中的特定檔案或整個目錄。

例如,在 JavaScript 專案中,忽略 node_modules/ 目錄有兩個好處:

  • 效能:在某些配置中,包含大量小型檔案的檔案樹可能會導致高 I/O 負載。
  • 多平台:如果主機 OS 或架構與容器不同,則無法共享已編譯的成品。

例如,在 Node.js 專案中,不建議同步 node_modules/ 目錄。儘管 JavaScript 是直譯語言,但 npm 套件可能包含無法跨平台移植的原生程式碼。

配置

watch 屬性定義了一系列規則,用於控制基於本地檔案變更的自動服務更新。

每條規則都需要一個 path 樣式以及偵測到修改時要執行的 actionwatch 有兩種可能的動作,根據 action 的不同,可能會接受或要求額外的欄位。

Watch 模式可用於多種不同的語言和框架。具體路徑和規則會因專案而異,但概念是一樣的。

先決條件

為了正常運作,watch 依賴常見的可執行檔。請確保您的服務映像檔包含以下二進位檔案:

  • stat
  • mkdir
  • rmdir

watch 還要求容器的 USER 對目標路徑具有寫入權限,以便更新檔案。一種常見的模式是使用 Dockerfile 中的 COPY 指令將初始內容複製到容器中。若要確保這些檔案由配置的使用者擁有,請使用 COPY --chown 旗標。

# Run as a non-privileged user
FROM node:18
RUN useradd -ms /bin/sh -u 1001 app
USER app

# Install dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install

# Copy source files into application directory
COPY --chown=app:app . /app

動作 (action)

Sync(同步)

如果 action 設定為 sync,Compose 會確保您在主機上對檔案所做的任何變更,都會自動與服務容器內對應的檔案保持一致。

sync 非常適合支援「熱重載」(Hot Reload) 或類似功能的框架。

更一般地說,對於許多開發使用案例,sync 規則可用於取代綁定掛載。

Rebuild(重建)

如果 action 設定為 rebuild,Compose 會自動使用 BuildKit 建構一個新的映像檔,並取代執行中的服務容器。

其行為與執行 docker compose up --build <svc> 相同。

Rebuild 非常適合編譯語言,或作為需要完整映像檔重建的特定檔案(例如 package.json)修改時的備用方案。

Sync + Restart(同步並重新啟動)

如果 action 設定為 sync+restart,Compose 會將您的變更與服務容器同步並重新啟動它們。

當設定檔變更且您不需要重建映像檔,只需重新啟動服務容器的主處理序時,sync+restart 是理想的選擇。例如,當您更新資料庫配置或 nginx.conf 檔案時,它會運作良好。

提示

利用 映像檔層快取多階段建構 來優化您的 Dockerfile,以加快增量重建速度。

path(路徑)與 target(目標)

target 欄位控制路徑如何對應到容器內。

對於 path: ./app/html 以及對 ./app/html/index.html 的變更:

  • target: /app/html -> /app/html/index.html
  • target: /app/static -> /app/static/index.html
  • target: /assets -> /assets/index.html

忽略 (ignore)

ignore 樣式是相對於目前 watch 動作中定義的 path,而非相對於專案目錄。在下方的範例 1 中,忽略路徑將相對於 path 屬性中指定的 ./web 目錄。

範例 1

這個最小範例針對具有以下結構的 Node.js 應用程式:

myproject/
├── web/
│   ├── App.jsx
│   ├── index.js
│   └── node_modules/
├── Dockerfile
├── compose.yaml
└── package.json
services:
  web:
    build: .
    command: npm start
    develop:
      watch:
        - action: sync
          path: ./web
          target: /src/web
          ignore:
            - node_modules/
        - action: rebuild
          path: package.json

在此範例中,當執行 docker compose up --watch 時,會使用從專案根目錄中的 Dockerfile 建構的映像檔來啟動 web 服務的容器。web 服務執行 npm start 指令,該指令會在打包工具(Webpack、Vite、Turbopack 等)中啟動已啟用熱模組重載 (Hot Module Reload) 的開發版本應用程式。

服務啟動後,watch 模式開始監控目標目錄和檔案。然後,每當 web/ 目錄中的原始碼檔案變更時,Compose 就會將該檔案同步到容器內 /src/web 下的對應位置。例如,./web/App.jsx 會被複製到 /src/web/App.jsx

複製完成後,打包工具會更新執行中的應用程式,無需重新啟動。

在這種情況下,ignore 規則將應用於 myproject/web/node_modules/,而不是 myproject/node_modules/

與原始碼檔案不同,新增依賴項無法即時完成,因此每當 package.json 變更時,Compose 都會重建映像檔並重新建立 web 服務容器。

許多語言和框架都可以遵循此模式,例如 Python 的 Flask:Python 原始檔可以同步,而對 requirements.txt 的變更則應觸發重建。

範例 2

調整先前的範例以示範 sync+restart

services:
  web:
    build: .
    command: npm start
    develop:
      watch:
        - action: sync
          path: ./web
          target: /app/web
          ignore:
            - node_modules/
        - action: sync+restart
          path: ./proxy/nginx.conf
          target: /etc/nginx/conf.d/default.conf

  backend:
    build:
      context: backend
      target: builder

此設定示範如何使用 Docker Compose 中的 sync+restart 動作,來高效開發並測試具有前端 Web 伺服器和後端服務的 Node.js 應用程式。該配置確保應用程式程式碼和設定檔的變更能夠被快速同步並套用,並且 web 服務會在需要時重新啟動以反映這些變更。

使用 watch

  1. compose.yaml 中為一個或多個服務新增 watch 區塊。
  2. 執行 docker compose up --watch 以建構並啟動 Compose 專案,並開啟檔案監控模式。
  3. 使用您偏好的 IDE 或編輯器編輯服務原始檔。
注意

如果您不想將應用程式日誌與(重)建構日誌和檔案系統同步事件混在一起,也可以使用專用的 docker compose watch 指令。

提示

查看 dockersamples/avatars,或用於 Docker 文件 本地設定,以取得 Compose watch 的示範。

參考

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.