使用 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
允許比繫結掛載更精細的粒度。監看規則允許您忽略受監視樹狀結構中的特定檔案或整個目錄。
例如,在 JavaScript 專案中,忽略 node_modules/
目錄有兩個好處
- 效能。具有許多小檔案的檔案樹狀結構在某些設定中可能會導致高 I/O 負載
- 多平台。如果主機作業系統或架構與容器不同,則無法共用已編譯的構件
例如,在 Node.js 專案中,不建議同步 node_modules/
目錄。即使 JavaScript 是直譯的,npm
套件也可能包含無法跨平台移植的原生程式碼。
設定
watch
屬性定義了一系列規則,這些規則根據本機檔案變更控制自動服務更新。
每個規則都需要一個 path
模式和在偵測到修改時要採取的 action
。watch
有兩種可能的動作,根據 action
的不同,可能會接受或要求其他欄位。
監看模式可以與許多不同的語言和框架一起使用。具體路徑和規則會因專案而異,但概念保持不變。
先決條件
為了正常運作,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 <svc>
相同。
重建功能適用於編譯語言,或是當特定檔案的修改需要完整重建映像檔時作為備用方案(例如 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
範例 1
這個最小範例以具有以下結構的 Node.js 應用程式為目標
myproject/
├── web/
│ ├── App.jsx
│ └── index.js
├── 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
作為其指令,然後啟動應用程式的開發版本,並在 bundler(Webpack、Vite、Turbopack 等)中啟用熱模組重新載入。
服務啟動後,監看模式會開始監控目標目錄和檔案。然後,只要 web/
目錄中的原始碼檔案發生變更,Compose 就會將檔案同步到容器內 /src/web
下的對應位置。例如,./web/App.jsx
會被複製到 /src/web/App.jsx
。
複製完成後,bundler 會更新正在執行的應用程式,無需重新啟動。
與原始碼檔案不同,新增新的依賴項無法即時完成,因此只要 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
- 在
compose.yaml
中的一個或多個服務中新增watch
區段。 - 執行
docker compose up --watch
來建置和啟動 Compose 專案,並啟動檔案監看模式。 - 使用您慣用的 IDE 或編輯器編輯服務原始碼檔案。
注意事項
如果您不希望應用程式日誌與(重新)建置日誌和檔案系統同步事件混在一起,也可以搭配專用的
docker compose watch
指令使用監看功能。
小技巧
查看
dockersamples/avatars
或 Docker 文件的本地設定 以取得 Composewatch
的示範。
意見回饋
我們正積極尋求有關此功能的意見反應。請在 Compose 規格儲存庫 中提供意見反應或回報您可能發現的任何錯誤。