docker compose watchで開発環境のホットリロードを実現する方法|sync・rebuild・sync+restartの使い分けと実践設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > docker compose watchで開発環境のホットリロードを実現する方法|sync・rebuild・sync+restartの使い分けと実践設計
「コードを修正してもコンテナを再起動しないと反映されない」「毎回 docker compose restart を叩くのが面倒」——Docker開発中にそう感じたことはないでしょうか。

Docker Compose v2.22 から正式機能になった docker compose watch を使えば、ファイルを保存した瞬間にコンテナへの反映が自動で走ります。手動での再起動は不要になり、開発の「変更→確認」ループが大幅に短縮されます。

この記事では、compose.ymldevelop ブロックの書き方から、syncrebuildsync+restart 3つのアクションの使い分け、Node.js アプリを使った実践例、よくあるトラブルの対処まで、実機で確認した手順を解説します。

動作確認環境:Docker Engine 26.1.4 / Docker Compose v2.27.1(Ubuntu 24.04 LTS)

この記事のポイント

・docker compose watch は v2.22+ で正式化された自動反映機能
・compose.yml の develop.watch ブロックに path・action・target を設定する
・sync(即時同期)・rebuild(再ビルド)・sync+restart(同期後再起動)を用途で使い分ける
・docker compose up --watch の一発起動でも同じ効果が得られる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

docker compose watch とは何か

Docker で開発するとき、よくある課題がこれです。

# 従来の開発フロー(手動再起動が必要) $ vim src/app.js # コードを編集 $ docker compose restart web # コンテナを再起動 $ curl localhost:3000 # 動作確認

この「編集→再起動→確認」を1日に何十回も繰り返す——それが docker compose watch で不要になります。

docker compose watch は、ホスト側のファイル変更を監視し、設定したルールに従ってコンテナへ自動反映します。React のホットリロードや nodemon による自動再起動と同じ感覚で、Compose のマルチサービス構成全体に適用できるのが特徴です。

バージョン要件

・Docker Compose v2.22.0 以降(2023年10月リリース)
・それ以前のバージョンでは docker compose alpha watch(アルファ機能)として存在していた
・Docker Desktop 4.24.0 以降は標準搭載

バージョンを確認するには以下を実行します。

$ docker compose version Docker Compose version v2.27.1

v2.22.0 未満の場合は docker compose alpha watch コマンドを試してください。v2.22.0 以降への更新が推奨です。

compose.yml の develop ブロックを書く

docker compose watch の設定はすべて compose.ymldevelop.watch セクションに書きます。基本構造は以下のとおりです。

services: web: build: . ports: - "3000:3000" develop: watch: - action: sync # アクション種別 path: ./src # 監視するホスト側パス target: /app/src # コンテナ内の同期先パス ignore: - node_modules/ # 監視除外パス - action: rebuild # 別のルール path: package.json

各フィールドの意味を整理しておきます。

action:変更時に実行する動作(sync / rebuild / sync+restart の3種類)
path:監視するホスト側のファイルまたはディレクトリ(compose.yml からの相対パス)
target:コンテナ内の同期先パス(sync・sync+restart アクションで必須)
ignore:監視から除外するパスのリスト(path からの相対指定)

1. sync アクションでファイルをリアルタイム同期する

sync は、変更されたファイルをコンテナを再起動せずにリアルタイムで書き込むアクションです。nodemon や Flask の debug モードなど、コンテナ内でファイル変更を検知して自動リロードするプロセスと組み合わせると、最も快適な開発体験が得られます。

develop: watch: - action: sync path: ./src target: /app/src ignore: - node_modules/ - "*.test.js"

ignore に node_modules/ を必ず入れる理由

path: ./src の下に node_modules/ ディレクトリがある場合、npm install で生成される大量のファイルが監視対象になってしまいます。変更のたびに不必要な同期が走るため、必ず除外してください。

2. rebuild アクションでイメージを再ビルドする

rebuild は、ファイル変更時に docker compose build を実行してイメージを再ビルドし、コンテナを再作成するアクションです。

develop: watch: - action: rebuild path: package.json - action: rebuild path: Dockerfile

package.json を変更すると npm install 相当の処理が再実行されます。ビルドキャッシュが有効なため、変更がない層はスキップされ、フルビルドより高速です。

rebuildtarget の指定が不要です(コンテナごと作り直すため)。

3. sync+restart で設定変更を即時反映する

sync+restart は、ファイルを同期してからコンテナプロセスを再起動するアクションです。イメージの再ビルドは行わないため、rebuild より高速です。

develop: watch: - action: sync+restart path: ./nginx.conf target: /etc/nginx/nginx.conf

nginx.conf を変更した場合、設定ファイルをコンテナに同期した後、nginx の設定を再読み込みするためにコンテナを再起動します。設定ファイルの変更反映に最適です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、docker compose watch を含む Compose の実践的な使い方をハンズオンで学べます。
Dockerハンズオン研修の詳細を見る >>

Node.js アプリを例にした実践的な compose.yml

実際の開発プロジェクトで使える構成例を示します。Node.js + Express アプリを nodemon で動かし、ソースコード変更時は sync で即時反映、依存関係変更時は rebuild で再インストールする設定です。

Dockerfile

FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["npx", "nodemon", "src/index.js"]

compose.yml

services: web: build: . ports: - "3000:3000" develop: watch: # src/ 以下を変更したら即時同期(nodemon が検知して自動再起動) - action: sync path: ./src target: /app/src ignore: - node_modules/ # package.json が変わったら再ビルド(npm install を再実行) - action: rebuild path: package.json

起動コマンド

# watch を有効にして起動する(推奨) $ docker compose up --watch # または別ターミナルで watch だけ起動する $ docker compose up -d $ docker compose watch

docker compose up --watch は v2.22 で追加された便利なフラグです。サービス起動と watch の両方を1コマンドで実行できます。

watch の動作確認とログの読み方

docker compose watch を実行すると、以下のようなログが出力されます。

$ docker compose up --watch [+] Building 12.3s (10/10) FINISHED [+] Running 1/1 ✔ Container myapp-web-1 Started Watch enabled - watching src, action sync to /app/src (ignoring node_modules/) - watching package.json, action rebuild # src/index.js を保存したとき Watch: Syncing service "web" after changes were detected: - "src/index.js" [web] [nodemon] restarting due to changes... [web] [nodemon] starting `node src/index.js` [web] Server listening on port 3000 # package.json を保存したとき Watch: Rebuilding service "web" due to changed files: - "package.json" [+] Building 8.4s (10/10) FINISHED [+] Running 1/1 ✔ Container myapp-web-1 Started

ログの見方を整理します。

Watch enabled:watch が正常に開始された
Syncing service "web":sync アクションが発動(ファイルを同期中)
Rebuilding service "web":rebuild アクションが発動(イメージを再ビルド中)
Restarting service "web":sync+restart アクションが発動

watch を停止するには Ctrl+C を押します。docker compose up -d でバックグラウンド起動している場合は、別ターミナルで watch を実行し、そこで Ctrl+C を押すと watch のみを停止できます(コンテナは動き続けます)。

トラブルシュート——watch が反応しない時の確認ポイント

1. Docker Compose のバージョンが古い

$ docker compose version Docker Compose version v2.18.1 ← v2.22 未満は非対応 # アップデート方法(Linux の場合) $ curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose $ chmod +x /usr/local/lib/docker/cli-plugins/docker-compose $ docker compose version Docker Compose version v2.27.1 ← アップデート成功

2. develop ブロックの階層が間違っている

よくある書き間違いは developvolumesenvironment と同じ階層に書けていないケースです。

# NG例:develop が services の外に出てしまっている services: web: build: . develop: # ← services: web: の下に入っていない watch: ... # OK例:develop は services > サービス名 の直下 services: web: build: . develop: # ← services: web: の下に正しく入っている watch: ...

3. path が compose.yml から見た相対パスになっていない

path は compose.yml があるディレクトリからの相対パスで指定します。./ を省略しても動作しますが、明示的に書いておくと分かりやすいです。

# NG例:絶対パスは使えない - action: sync path: /home/user/myapp/src # 動作しない # OK例:compose.yml からの相対パス - action: sync path: ./src # compose.yml と同じ階層の src/

4. bind mount と watch を同時に使っている

volumes でバインドマウントを設定しているサービスに develop.watch を追加すると、どちらが優先されるか混乱しやすい点に注意が必要です。両方設定した場合、バインドマウントの方が優先されます。開発中は watch を使う方向で整理し、bind mount の定義を削除するのが推奨です。

# 整理前(bind mount と watch の混在) services: web: volumes: - ./src:/app/src # bind mount develop: watch: - action: sync # watch も設定(競合しやすい) path: ./src target: /app/src # 整理後(watch に統一) services: web: develop: watch: - action: sync path: ./src target: /app/src ignore: - node_modules/

本記事のまとめ

docker compose watch の3つのアクションを用途別に整理します。

アクション 動作 主な用途 速度
sync ファイルをコンテナへ即時同期(再起動なし) ソースコード変更(nodemon・Flask debug と組み合わせ) 最速
rebuild イメージを再ビルドしてコンテナを再作成 Dockerfile・package.json・requirements.txt の変更 遅め(ビルド時間込み)
sync+restart ファイル同期後にコンテナを再起動(リビルドなし) nginx.conf など設定ファイルの変更 中程度

実際の開発では1つのサービスに複数のルールを組み合わせます。「src/ は sync で即時反映、package.json は rebuild でパッケージ再インストール」というように、変更の種類ごとに最適なアクションを割り当てることが、快適な開発ループの鍵です。

docker compose watch は v2.22 以降で正式機能として安定しているため、まず手元の Docker Compose のバージョンを確認するところから始めてみてください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが Docker の基礎から Compose の実践設計まで解説します。
Dockerハンズオン研修の詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。