使用 Compose Watch
watch
屬性會在您編輯和儲存程式碼時自動更新和預覽執行中的 Compose 服務。對於許多專案而言,這使得 Compose 執行後無需動手操作即可完成開發工作流程,因為服務會在您儲存工作時自動更新自身。watch
遵循以下檔案路徑規則
- 所有路徑相對於專案目錄
- 遞迴監視目錄
- 不支援萬用字元模式
- 來自
.dockerignore
的規則適用- 使用
ignore
選項定義要忽略的其他路徑(語法相同) - 自動忽略常見 IDE(Vim、Emacs、JetBrains 等)的臨時/備份檔案
- 自動忽略
.git
目錄
- 使用
您無需為 Compose 專案中的所有服務開啟 watch
。在某些情況下,可能只適合將專案的一部分(例如 Javascript 前端)進行自動更新。
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
作為其命令,然後啟動應用程式的開發版本,並在捆綁器(Webpack、Vite、Turbopack 等)中啟用熱模組過載。
服務啟動後,監視模式開始監視目標目錄和檔案。然後,每當 web/
目錄中的原始檔發生更改時,Compose 會將檔案同步到容器內 /src/web
下的相應位置。例如,./web/App.jsx
會被複制到 /src/web/App.jsx
。
複製後,捆綁器會更新正在執行的應用程式,無需重新啟動。
與原始碼檔案不同,無法即時新增新的依賴項,因此每當 package.json
發生更改時,Compose 都會重新構建映象並重新建立 web
服務容器。
此模式可用於許多語言和框架,例如 Python with 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
- 在
compose.yaml
中向一個或多個服務新增watch
部分。 - 執行
docker compose up --watch
以構建和啟動 Compose 專案並啟動檔案監視模式。 - 使用您首選的 IDE 或編輯器編輯服務原始檔。
提示
如果您不想將應用程式日誌與(重新)構建日誌和檔案系統同步事件混合在一起,也可以將 watch 與專用的
docker compose watch
命令一起使用。
正在尋找一個測試示例專案嗎?
檢視
dockersamples/avatars
,或 Docker 文件的本地設定 以演示 Composewatch
。
反饋
我們正在積極徵求對該功能的反饋。請在 Compose 規範倉庫 中提供反饋或報告您可能發現的任何錯誤。