Skip to main content

第23章:Compose Watchで「再ビルド地獄」から脱出 👀🔁🧨

開発中って、ちょっとTypeScriptを直しただけなのに… **「再ビルド→待つ→コンテナ再起動→待つ」**が毎回発生して、テンション下がりがち😇💤

そこで Compose Watch の出番!🎉 **変更されたファイルだけをコンテナへ同期(sync)**し、必要なときだけ rebuild / restartすることで、待ち時間をグッと減らせます。(Docker Documentation)


1) Compose Watchの考え方 🧠✨

ざっくり言うと、開発の変更を **3段階の“反映ルート”**に分けます👇

  • 🟢 sync:ファイルだけコピー(最速)
  • 🟡 sync+restart:コピーした上でサービスを再起動(中速)
  • 🔴 rebuild:イメージ再ビルド→作り直し(最遅、でも必要)

Composeの設定は compose.yaml の各サービスに develop: watch: を書いて、監視ルールを並べる感じです。(Docker Documentation)


2) 3アクションの使い分け(超重要)🎯

🟢 sync(基本はコレ)

  • 変更のたびに コンテナ内の指定パスへコピー
  • その後の反映は、Node側のホットリロード(Vite/Next等)やwatch機能に任せる (Docker Documentation)

✅向いてる:src/routes/controllers/、テンプレ・静的ファイルなど🧩


🟡 sync+restart(「アプリが自力で拾えない」時)

✅向いてる:nginx.conf、環境設定ファイル、Nodeがwatchしない系の実行形態(素のnode実行など)🧯


🔴 rebuild(依存が変わった時だけ)

  • 依存関係が変わると、コンテナ内で“差分だけ反映”ができないことが多いので その時だけ rebuildが正解💡 package.json やロックファイル変更をトリガーにするのが定番です。(Docker Documentation)

✅向いてる:package.json / package-lock.json / pnpm-lock.yaml / yarn.lock など📦


3) 最小レシピ(TypeScript向け)🍳🧑‍💻

ここでは「普段はsync」「依存だけrebuild」の王道パターンにします✨ ポイントは node_modulesを同期対象から外すこと!🚫📁(巨大で遅い&環境差が出やすい)

## compose.yaml(例)
services:
app:
build: .
command: npm run dev
develop:
watch:
# ① ソースは同期(最速)
- action: sync
path: ./src
target: /app/src
initial_sync: true
ignore:
- node_modules/

# ② 設定ファイルは同期+再起動(必要なら)
- action: sync+restart
path: ./tsconfig.json
target: /app/tsconfig.json

# ③ 依存が変わったらrebuild(必要な時だけ)
- action: rebuild
path: package.json
- action: rebuild
path: package-lock.json
  • ignore のパスは そのwatchルールの path を起点にした相対になるので注意!😵‍💫 (例:path: ./src なら ignore: node_modules/./src/node_modules/ を意味する)(Docker Documentation)
  • initial_sync: true を入れると、watch開始時に「まず同期してから」スタートしやすいです👍(Docker Documentation)

4) 起動コマンド:どっちを使う?⌨️

✅ ふつうはこっち(ログも全部見える)

docker compose up --watch

docker compose up には -w/--watch があり、ファイル更新に合わせて rebuild/refresh できます。(Docker Documentation)

✅ watchログだけ見たいならこっち

docker compose watch

docker compose watch はwatch専用コマンドで、オプションに --no-up(先に起動しない)などもあります。(Docker Documentation) さらに、公式ドキュメントでも「アプリログとwatchログが混ざるのがイヤなら専用コマンドを使えるよ」と説明されています。(Docker Documentation)


5) “再ビルド地獄”を終わらせる設計のコツ 🧱⚡️

✅ 監視対象は「小さく」「意味ごとに分ける」📏

  • src/:sync(超頻繁に変わる)
  • config:sync+restart(変わるが再起動が必要)
  • package*.json:rebuild(依存だけ)

こうすると、普段の編集は ほぼsyncだけで完結します🚀


6) Windowsでの体感速度を上げる小ワザ 🪟🐢➡️🪟⚡️

ファイルI/Oが絡むと、置き場所次第で体感が変わりやすいです💦 Docker公式は WSL 2 を使うときは、コードをLinux側(WSLのディストリビューション内)に置くのを推奨しています。(Docker Documentation) Docker DesktopのWSL統合の流れや確認方法(wsl.exe -l -v など)も公式ガイドにまとまっています。(Docker Documentation)

「なんかwatchが重い…」ってとき、まずここが効くこと多いです💡🛠️


7) よくある事故&即復旧 tips 😭🧯

😭 変更しても何も起きない

😭 syncは走るのにアプリが反映しない

  • アプリ側がファイル監視してない可能性大! → sync+restart を使う or Node側のwatch設定を見直す👀🔁(Docker Documentation)

😭 rebuildが頻発してしまう

  • rebuildpath が広すぎる(例:./ を指定) → rebuildは 依存ファイルだけに絞る📦✂️(Docker Documentation)

😭 node_modulesが同期されて爆遅

  • ignore を入れて止血!🚑 しかも ignorepath 起点の相対なのでそこだけ注意!(Docker Documentation)

🧪 ミニ演習:30分で「待たない開発」にする ⏱️🎮

ゴール 🎯

  • src の編集 → 即反映(sync)
  • package.json 変更 → rebuildが走る

手順 🧩

  1. compose.yaml に上のwatch設定を入れる
  2. これで起動👇
docker compose up --watch

(Docker Documentation)

  1. src の適当なファイルを1行変更 → watchログでsyncが出るか確認👀✨
  2. package.json を少し変更(依存を増やす/スクリプト名変える等)→ rebuildが走るか確認🔥

成果チェック ✅

  • ✅ 普段の編集で rebuild がほぼ起きない
  • ✅ 依存をいじった時だけ rebuild が起きる
  • ✅ node_modules が同期されてない(ログや挙動で確認)

🤖 AI活用(Copilot / Codex向け)プロンプト集 🧠💬

① watch設計を“最短で”提案してもらう

Docker Compose Watchの設定を作ってください。
条件:
- 変更頻度が高い src は sync
- tsconfig など設定は sync+restart
- package.json とロックファイルは rebuild
- node_modules は絶対に同期しない
プロジェクト構成は以下:
(ここに tree を貼る)
compose.yaml の差分で出してください。

② 「なんで反映されない?」デバッグ

docker compose up --watch を使っていますが、編集しても反映されません。
以下を見て原因候補を優先度順に出してください:
- compose.yaml(貼る)
- Dockerfile(貼る)
- コンテナの作業ディレクトリと command(貼る)
最後に“最小の修正差分”を提案してください。

③ rebuild頻発の原因を特定

Compose Watchでrebuildが頻発しています。
watchルールのどれが原因になり得るか指摘し、
rebuild対象を依存ファイルのみに絞る改善案を出してください。
(compose.yaml の develop.watch を貼る)

まとめ 🏁✨

Compose Watchは、開発のループをこう変えてくれます👇

  • ✍️ 普段:syncで即反映(待たない)
  • 🧩 設定系:sync+restartで安全に反映
  • 📦 依存:rebuildは“必要な時だけ”

これで「再ビルド地獄」かなり終わります😆🔥

次の章(第24章)の「ターゲット/プロファイル戦略」と合わせると、**“変更箇所だけ最短ルートで動かす”**が完成してさらに気持ちいいですよ🚦⚡️