Docker Compose Watch:Docker開発をローカル環境のように快適にする「武器」

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

1行の修正に1分のビルド待ち:エンジニア共通の悩み

開発現場ではおなじみの無限ループがあります。コード修正 → 保存 → docker-compose up --build を実行 → イメージのビルドが終わるまで数十秒待機 → ブラウザで確認. もし1日に100回コードを直すとすれば、この「待ち時間」だけで貴重な1〜2時間が消えてしまうことになります。

これまでの定番の解決策は、Bind Mounts(バインドマウント)を使用してコードフォルダをコンテナにマウントすることでした。この方法は一見便利ですが、パーミッションの問題が発生したり、ホスト側とコンテナ側の node_modules が競合したりすることがよくあります。特に、新しいライブラリを追加した場合にはバインドマウントだけでは対応できず、結局イメージを一からビルドし直す必要がありました。

こうした煩わしさを解消するために登場したのが Docker Compose Watch です。これは単なるファイルマウントではなく、インテリジェントな同期メカニズムにより、Docker上での開発をローカル環境で直接実行しているかのようなスムーズな体験に変えてくれます。

Docker Compose Watch の仕組み

簡単に言えば、Docker Compose Watch はプロジェクトディレクトリ内のすべての変更を静かに監視する「探偵」のようなものです。Ctrl+Sを押した瞬間、設定に応じて以下の3つのアクションのいずれかを実行します。

  • Sync: ファイルを即座にコンテナへ転送します(通常1秒未満で、フロントエンドのホットリロードに最適です)。
  • Rebuild: 設定ファイル(package.jsonrequirements.txt)が変更された際、自動的にイメージを再ビルドしてコンテナを再起動します。
  • Sync + Restart: ファイルを転送した後にサービスを再起動します(自己リロード機能を持たないバックエンドなどで使用します)。

すべてはバックグラウンドで自動的に行われます。開発者はコードを書くことに集中し、残りの作業は Docker に任せましょう。

Node.js プロジェクトでの設定例

具体的なイメージを掴むために、基本的な Node.js プロジェクトを例に挙げます。ディレクトリ構造が以下のようになっていると仮定します:

my-app/
├── src/
│   └── index.js
├── package.json
└── compose.yaml

ステップ1:compose.yaml ファイルの調整

従来の volumes だけでなく、監視機能を有効にするために develop ブロックを追加します:

services:
  web:
    build: .
    ports:
      - "3000:3000"
    develop:
      watch:
        - path: ./package.json
          action: rebuild
        - path: ./src
          action: sync
          target: /app/src
          ignore:
            - node_modules/

重要なパラメータの解説:

  • path: ./package.json:このファイルが変更(ライブラリの追加など)されると、action: rebuild が実行されます。コマンドを打つ必要なく、Docker が自動的にイメージを再ビルドして新しいライブラリを反映します。
  • path: ./src:src フォルダ内のすべての変更は、即座に target: /app/srcsync(同期)されます。
  • ignorenode_modules のような重いフォルダを除外し、動作を軽くします。

ステップ2:Watch モードの起動

通常の up コマンド의 대신に、以下を実行します:

docker compose watch

これで Docker はコンテナを起動し、バックグラウンドプロセスを維持します。index.js 内のログ出力を一行修正して保存してみてください。遅延を感じることなく、コンテナに新しいコードが反映されるのがわかるはずです。

Bind Mount から Watch へ移行すべき理由

「ボリュームをマウントするだけでも十分速いのでは?」と疑問に思うかもしれません。しかし、Watch には強力な3つのメリットがあります:

  1. 圧倒的なスピード: macOS や Windows では、仮想化レイヤーを介した Bind Mount はファイル数が多いと遅くなりがちです。Watch はイベントベースのメカズムを採用しているため、非常に軽量に動作します。
  2. 正確な制御: Watch では同期が必要なファイルを正確に指定できます。ホスト側の不要なファイルが Docker 内のクリーンな環境を壊す心配がありません。
  3. 完全な自動化: ライブラリ追加時に自動で rebuild する機能は、Bind Mount では決して実現できない利点です。

実測データ:リソースを40%削減

ファイル監視プロセスを動かすとPCが重くなるのでは、と懸念される方もいるでしょう。しかし、適切にフォルダを ignore(除外)すれば、実際にはその逆の結果が得られます。

30以上のコンテナが動く実際のプロジェクトで、サードパーティの同期ツール(Mutagen や Docker Sync など)を廃止して Compose Watch に一本化したところ、CPU使用率を40%削減できました。 私の経験上、develop 部分を別ファイルに分けるか、extends を使用してメインの compose.yaml をスッキリ保つのがおすすめです。

大規模なプロジェクトでは、ロジック部分には action: sync を優先し、マニフェストファイルに対してのみ rebuild を使うようにしましょう。

トラブルを避けるための注意点

  • バージョン確認:Docker Desktop 4.24 または Docker Compose 2.22.0 以上が必要です。今すぐ docker compose version で確認してください。
  • アプリのホットリロード:Docker Watch はファイルをコンテナに送るだけです。アプリが自動的に再読み込みされるかどうかは、使用しているコード(Node.js の nodemon や Python の uvicorn --reload など)に依存します。

終わりに

Docker Compose Watch は、ローカル環境とコンテナ環境の境界線をなくす画期的な進歩です。退屈な繰り返し作業から解放され、よりクリエイティブなコーディングに集中できるようになります。毎日 Docker を使っているなら、今すぐ Watch を試してみてください。もう以前のやり方には戻りたくなくなるはずです。

セットアップで困ったことはありませんか?ぜひコメント欄で教えてください。全力でサポートします!

Share: