使用 Compose Watch
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
檔案時,它會很好地工作。
提示
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
模式相對於當前 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
- 將
watch
部分新增到compose.yaml
中的一個或多個服務。 - 執行
docker compose up --watch
以構建和啟動 Compose 專案並啟動檔案監視模式。 - 使用您喜歡的 IDE 或編輯器編輯服務原始檔。
注意如果您不想讓應用程式日誌與(重新)構建日誌和檔案系統同步事件混在一起,Watch 也可以與專用的
docker compose watch
命令一起使用。
提示檢視
dockersamples/avatars
或 Docker docs 的本地設定,以演示 Composewatch
。