使用 Compose Watch

要求: Docker Compose 2.22.0 及更高版本

watch 屬性會在您編輯和儲存程式碼時自動更新並預覽您正在執行的 Compose 服務。對於許多專案,這使得一旦 Compose 執行起來,就可以實現免手動開發工作流,因為當您儲存工作時,服務會自動更新。

watch 遵循以下檔案路徑規則

  • 所有路徑都相對於專案目錄,除了忽略檔案模式
  • 目錄被遞迴監視
  • 不支援 glob 模式
  • 應用 .dockerignore 中的規則
    • 使用 ignore 選項定義要忽略的其他路徑(語法相同)
    • 常見 IDE(Vim、Emacs、JetBrains 等)的臨時/備份檔案會自動忽略
    • .git 目錄會自動忽略

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

Compose Watch 旨在與使用 build 屬性從本地原始碼構建的服務配合使用。它不會跟蹤依賴於 image 屬性指定預構建映象的服務所做的更改。

Compose Watch 與繫結掛載

Compose 支援在服務容器內共享主機目錄。Watch 模式不取代此功能,而是作為專門適用於容器內開發的伴侶而存在。

更重要的是,watch 允許比繫結掛載更細粒度的控制。Watch 規則允許您忽略監視樹中的特定檔案或整個目錄。

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

  • 效能。在某些配置中,包含許多小檔案的檔案樹可能會導致高 I/O 負載。
  • 多平臺。如果主機作業系統或架構與容器不同,則無法共享編譯後的工件。

例如,在 Node.js 專案中,不建議同步 node_modules/ 目錄。即使 JavaScript 是解釋型語言,npm 包也可能包含不可跨平臺移植的本機程式碼。

配置

watch 屬性定義了一組規則,這些規則根據本地檔案更改控制服務的自動更新。

每個規則都需要一個 path 模式和在檢測到修改時要執行的 action。對於 watch 有兩種可能的操作,並且根據 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,Compose 會確保對主機上檔案所做的任何更改都會自動與服務容器中對應的檔案匹配。

sync 非常適合支援“熱過載”或類似功能的框架。

更一般地說,sync 規則可以替代繫結掛載用於許多開發用例。

重建

如果 action 設定為 rebuild,Compose 會自動使用 BuildKit 構建新映象並替換正在執行的服務容器。

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

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

同步 + 重啟

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

當配置檔案更改且您不需要重建映象,而只需重啟服務容器的主程序時,sync+restart 是理想的選擇。例如,當您更新資料庫配置或 nginx.conf 檔案時,它會很好地工作。

提示

使用映象層快取多階段構建最佳化您的 Dockerfile,以實現快速增量重建。

pathtarget

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 模式相對於當前 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 等)中啟用熱模組過載。

服務啟動後,watch 模式開始監視目標目錄和檔案。然後,只要 web/ 目錄中的原始檔發生更改,Compose 就會將檔案同步到容器內 /src/web 下的相應位置。例如,./web/App.jsx 被複制到 /src/web/App.jsx

複製後,捆綁器會更新正在執行的應用程式而無需重新啟動。

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

與原始碼檔案不同,新增新依賴項無法即時完成,因此只要 package.json 更改,Compose 就會重建映象並重新建立 web 服務容器。

這種模式可以應用於許多語言和框架,例如帶有 Flask 的 Python: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. watch 部分新增到 compose.yaml 中的一個或多個服務。
  2. 執行 docker compose up --watch 以構建和啟動 Compose 專案並啟動檔案監視模式。
  3. 使用您喜歡的 IDE 或編輯器編輯服務原始檔。
注意

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

提示

檢視 dockersamples/avatarsDocker docs 的本地設定,以演示 Compose watch

參考