はじめに
普段、開発環境ではDockerを使っていますが、Dockerの Compose Watch とやらが便利と聞きました!
最近Dockerの勉強もしていなかったので、今回はCompose Watchを実際に動かしながら学んでいきます。
Compose Watchとは?
Compose Watchは、ファイルの変更を監視して、変更に応じた処理を自動で実行してくれる機能です。
compose.yaml の develop.watch に設定します。
develop:
watch:
- action: sync
path: ./src
target: /app/src
起動するときは、
docker compose up --watch
を実行します。
ざっくりいうと、
ファイルを変更
↓
Compose Watchが検知
↓
設定したactionを実行
という仕組みです。
そしてCompose Watchには、次の5つのactionがあります。
今回は、この5つを実際に動かして違いを確認します。
今回の検証環境
検証用に、actionごとにファイルを用意しました。
~/develop/docker_use_watch/lab/watch-actions$ tree
.
├── Dockerfile
├── app.py
├── compose.yaml
├── files
│ ├── rebuild.txt
│ ├── restart.txt
│ ├── sync-exec.txt
│ ├── sync-restart.txt
│ └── sync.txt
└── observe.sh
1 directory, 9 files
actionごとに別のサービスを起動します。
sync :8081
rebuild :8082
restart :8083
sync+restart :8084
sync+exec :8085
レスポンスでは、
message=sync v1
started_at=2026-08-16T11:10:43
hostname=cf99849c1a59
を確認します。
-
message:ファイルの内容が変わったか -
started_at:プロセスが再起動したか -
hostname:コンテナが作り直されたか
それでは実際に動かします。
syncとは
sync は、変更したファイルを実行中のコンテナへ反映するactionです。
実際に sync.txt を v1 → v2 に変更してみます。
設定はこちらです。
develop:
watch:
- action: sync
path: ./files/sync.txt
target: /app/content.txt
initial_sync: true
ファイルを変更すると、
message=sync v1
↓
message=sync v2
になりました。
started_at と hostname は変わっていません。
つまり、
sync = ファイルだけ反映する
です。
rebuildとは
rebuild は、Docker Imageを再ビルドして、コンテナも作り直すactionです。
実際に rebuild.txt を変更してみます。
設定はこちらです。
develop:
watch:
- action: rebuild
path: ./files/rebuild.txt
ファイルを変更するとDocker buildが走り、新しいコンテナが起動しました。
started_at も hostname も変わります。
つまり、
rebuild = Docker Imageから作り直す
です。
restartとは
restart は、コンテナを再起動するactionです。
実際に restart.txt を変更してみます。
設定はこちらです。
volumes:
- ./files/restart.txt:/app/content.txt
develop:
watch:
- action: restart
path: ./files/restart.txt
ここでポイントなのが、restart 自体はファイルを同期しないことです。
今回はbind mountを使っているため、変更したファイルをコンテナから見ることができます。
started_at は変わりますが、hostname は変わりません。
つまり、
restart = 再起動だけする
です。
sync+restartとは
sync+restart は、ファイルを反映してからコンテナを再起動するactionです。
実際に sync-restart.txt を変更してみます。
設定はこちらです。
develop:
watch:
- action: sync+restart
path: ./files/sync-restart.txt
target: /app/content.txt
initial_sync: true
動きはシンプルです。
ファイル変更
↓
sync
↓
restart
つまり、
sync+restart = ファイル反映 + 再起動
です。
sync+execとは
sync+exec は、ファイルを反映したあとに、指定したコマンドを実行するactionです。
実際に sync-exec.txt を変更してみます。
設定はこちらです。
develop:
watch:
- action: sync+exec
path: ./files/sync-exec.txt
target: /app/content.txt
initial_sync: true
exec:
command: ["kill", "-HUP", "1"]
今回はファイルを同期したあと、
kill -HUP 1
を実行して、アプリにファイルを読み直させています。
コンテナ自体は再起動しません。
つまり、
sync+exec = ファイル反映 + コマンド実行
です。
5つのactionを整理
実際に動かしてみると、違いはシンプルでした。
| action | ざっくり何をする? |
|---|---|
sync |
ファイルだけ反映 |
rebuild |
Docker Imageから作り直す |
restart |
再起動だけ |
sync+restart |
ファイル反映 + 再起動 |
sync+exec |
ファイル反映 + コマンド実行 |
もう少し細かく見ると、
| action | ファイル同期 | 再起動 | Image再ビルド |
|---|---|---|---|
sync |
○ | × | × |
rebuild |
- | ○ | ○ |
restart |
× | ○ | × |
sync+restart |
○ | ○ | × |
sync+exec |
○ | × | × |
Goのホットリロードにも使える?
Compose Watchを知ったとき、
Compose WatchがあればAirはいらないのでは?
と思いました。
ただ、役割は少し違います。
たとえば sync を使うと、
main.go変更
↓
Compose Watch
↓
コンテナへsync
まではできます。
ただし、Goはソースコードを同期しただけでは、実行中のバイナリは変わりません。
そこでAirと組み合わせると、
main.go変更
↓
Compose Watch
↓
sync
↓
Airが変更を検知
↓
go build
↓
再起動
という使い方ができます。
もちろん、Airを使わずに rebuild でコンテナごと作り直すこともできます。
なので、
Compose Watch
→ ファイル変更に対してDocker側で何をするか
Air
→ Goをbuildして再起動する
くらいに考えると分かりやすそうです。
まとめ
Compose Watchは、
ファイル変更を検知して、その変更に応じたactionを実行する機能
でした。
今回実際に5つ動かしてみて、次のように覚えると分かりやすかったです。
sync
→ ファイルだけ反映
rebuild
→ Docker Imageから作り直す
restart
→ 再起動だけ
sync+restart
→ ファイル反映 + 再起動
sync+exec
→ ファイル反映 + コマンド実行
最初は「Dockerのホットリロード機能なのかな?」と思っていましたが、実際に触ってみると、
「ファイルが変わったときに、Docker側で何をするかを決める機能」
と考えるのが一番分かりやすかったです。





