Docker Compose Watchで保存した変更が反映されないときは、「Watchが起動しているか」「変更がルールに一致したか」「コンテナへ同期・再構築されたか」「アプリが変更を読み直したか」の4段階に分けて確認します。syncはファイルをコンテナへ合わせる機能であり、アプリの再読込や依存パッケージの再インストールまで自動で保証するものではありません。
Compose Watchは、ローカルのソースからbuildする開発用サービスを対象とする仕組みです。Docker公式のCompose Watchガイドでは、既成イメージをimageだけで使うサービスは変更追跡の対象外とされています。ただし、imageとbuildを併記したサービスまで非対応という意味ではありません。
以下は2026年10月4日時点のDocker公式資料に基づく確認手順です。
最初にComposeのバージョンとアクションを確認する
| 機能 | 必要なDocker Compose | 動作 |
|---|---|---|
develop.watch、sync、rebuild | 2.22.0以降 | 同期、またはイメージ再構築とコンテナ再作成 |
sync+restart | 2.23.0以降 | 同期後にコンテナを再起動 |
restart、sync+exec | 2.32.0以降 | 再起動、または同期後にコマンド実行 |
sync+execのexec設定 | 2.32.2以降 | 実行コマンドやユーザーなどを指定 |
対応版はCompose Develop Specificationで確認できます。まず次を実行し、想定したComposeを呼び出しているか確認してください。
docker compose version
docker compose config
docker compose configでは、対象サービスにbuildとdevelop.watchが残っているか、別のComposeファイルやプロジェクト指定を読んでいないかを確認します。環境変数などが展開されることがあるため、出力をそのまま公開しないでください。
表は各アクションの最低対応版です。initial_syncやincludeなどの追加項目まで、2.22.0以降のすべての版で使えるという意味ではありません。利用中の版で設定が認識されるかはdocker compose configで確認し、未対応項目のエラーが出たら、その項目に対応するComposeへ更新してください。
最小のWatch設定
以下は既存の開発プロジェクトへ追加するWatch設定例です。プロジェクトのDockerfile、コンテナ内の/app/src配置、package.jsonのdevスクリプトがあることを前提にしています。
services:
app:
build: .
command: npm run dev
develop:
watch:
- action: sync
path: ./src
target: /app/src
initial_sync: true
ignore:
- node_modules/
- action: rebuild
path: package.json
この例では、src配下の変更は同期し、package.jsonの変更はイメージを再構築します。ソース同期後の画面更新は、npm run devで起動した開発サーバー側のhot reloadに依存します。
ignore: node_modules/は、この例ではsrc/node_modules/を指します。プロジェクト直下のnode_modulesは監視対象のsrc外です。また、利用するlockfileの変更でも依存インストールが必要なら、その実ファイルに対応するrebuildルールを追加してください。

反映されない場所を順番に切り分ける
- Watchを実際に開始する:
docker compose up --watch、またはdocker compose watchを実行します。通常のdocker compose up -dだけでWatchが継続していると決めつけないでください。既存コンテナだけを監視する場合の--no-upは、監視前のbuildとstartを省略するオプションです。詳細はdocker compose watchリファレンスにあります。 - 監視イベントを見る:
watch.path内の無害なファイルを保存し、Watchを実行している端末に同期や再構築のイベントが出るか確認します。何も出なければ、実行ディレクトリ、-fで指定したファイル、対象サービス名を見直します。 - pathと除外条件を照合する:
pathはプロジェクトディレクトリからの相対指定で、ディレクトリは再帰監視されます。path: ./src/**/*.jsのようなglobは使わず、対象を絞る場合はinclude、除外はignoreを使います。ignoreは各watch.pathからの相対指定で、build contextの.dockerignoreも暗黙に作用します。 - コンテナ側の実ファイルを見る:イベントが出たら、
docker compose exec app shなどでtarget側の同じファイルを確認します。ホストだけを見て同期成功と判断しないでください。 - 書き込み条件を確認する:Watchにはコンテナ内の
stat、mkdir、rmdirと、サービスのUSERがtargetへ書き込める権限が必要です。初期ファイルの所有者はDockerfileのCOPY --chownなどで整えます。原因を確認せずchmod 777やroot実行へ変える方法は避けます。 - アプリの再読込を確認する:ファイルが変わっているのに表示が古いなら、アプリが実際にそのパスを参照しているか、hot reloadが有効かを確認します。設定ファイルなど再起動で読まれるものは
sync+restart、依存manifestやコンパイル工程が必要な変更はrebuildが候補です。
Docker公式Quickstartも、ソースの同期と、依存ファイル変更時のrebuildを分けています。公式Quickstartのように、Composeの同期とアプリ側の再読込を別の処理として考えるのがポイントです。
開始前の変更だけ合わない場合
initial_sync: trueは、既存コンテナで新しいWatchセッションを始めるとき、監視対象ファイルが一致しているか確認する設定です。Watch開始後の保存を検知する機能そのものとは役割が違います。開始前に変更したファイルだけ古い場合は、initial_syncと、DockerfileのCOPY対象、.dockerignoreを確認してください。
よくある質問
imageがあるとWatchは使えませんか?
imageだけの既成イメージサービスは対象外ですが、公式仕様にはimageとbuildを併記した例があります。ローカルソースからbuildする設定があるかで判断します。
syncすれば依存パッケージも更新されますか?
自動ではありません。manifestやlockfile変更時にインストールを含むイメージ再構築が必要なら、別のrebuildルールを用意します。
未反映ならvolumeを削除すべきですか?
通常の第一手ではありません。まずWatchイベント、コンテナ側ファイル、権限、アプリ再読込を確認します。原因不明のままdown -vでデータを消さないでください。
まとめ
Compose Watchの未反映は、監視、ルール一致、同期・再構築、アプリ再読込を分けると切り分けやすくなります。syncでファイルが届いているなら次にアプリ側を確認し、届いていないならpath、除外条件、権限へ戻ってください。


コメント