LoginSignup
6
7

ローカルコンテナのホットリロードにDocker Compose Watchはいかが?

Last updated at Posted at 2024-02-21

はじめに

この記事はローカルの開発環境でコンテナを用いている人に向けた開発効率化を目的としたものです。

dockerのようなコンテナ技術を用いてローカル開発を行うことにはさまざまなメリットがあります。例えば

  • 開発環境の共通化
  • 開発環境構築の難易度軽減
  • ローカルマシンをクリーンに保てる

などです。
しかし、同様にいくつかの課題も存在し、その中の一つとして工夫しないとホットリロードができない、というものがあります😭

今回はその「工夫しないとホットリロードができない」を簡単に解決してくれる機能であるDocker Compose Watchを紹介したいと思います!

従来のコンテナを用いたホットリロードな開発環境

インタープリタ型言語

JavaScriptなどのインタープリタ型言語では再ビルドの必要がないため、次のようにソースコードが格納されたディレクトリを丸ごとコンテナにマウントするケースが多かったかと思います。

conpose.yaml
version: "3.8"

services:
  my-app:
    container_name: my-app
    build:
      context: .
    tty: true
    volumes:
      - ./src:/app/src:cached
    ports:
      - 3000:3000

しかし、node_modulesのようなインストールしたライブラリを扱うディレクトリはlinterなどの開発のみに使うようなライブラリも含んでおり、そのままマウントされては困る場面が存在します。そのため、package.jsonの更新が入った場合はコンテナをビルドし直す、といった方針を取られていた方も多いのではないでしょうか :thinking:

コンパイル型言語(or JVM系言語)

Goなどのコンパイル言語は基本的にはコンパイルし直さないとソースコードの変更がアプリに反映されないため、ソースコードを変更するたびに再ビルド、あるいはライブラリなどでホットリロードを可能にした上でコンテナ内部に入って開発する、といったことが多かったかと思います。
しかし、ソースコードの更新のたびにコンテナを手動でビルドし直すのは手間です。また、ホットリロードを有効化してコンテナ内部で開発を行うのにはコンテナ内部での開発が快適に行えるような専用の環境やIDE側でのセットアップが必要であり、すでに環境が整っているようなケースを除いては準備が手間ですし、環境構築の難易度も高くなってしまいがちです :cry:

そこでDocker Compose Watchの出番です。

Docker Compose Watchとは?

Docker Compose Watchとは、Docker Composeに内蔵されている機能の一つでローカルファイルの変更を検知し、コンテナ内部のファイルを置き換えたり、コンテナを再ビルドしてくれる機能です。
compose.yaml or docker-compose.yamlに規定の項目を書いた上で

docker compose watch

のコマンドを実行することで使用できます!
Docker Compose Watchにはsyncrebuildの二つの機能があり、それぞれ

  • syncは追跡中のローカルのファイルに変更が生じたら、自動で実行中のコンテナ内のファイルを設定通りに置き換える
  • rebuildは追跡中のローカルのファイルに変更が生じたら、自動でコンテナを再ビルドする

といった機能となっています!

下記で例を見てみましょう!

Docker Compose Watchを用いたホットリロードな開発環境

インタープリタ型言語

例えばpackage.jsonをプロジェクトルートディレクトリに含み、./src以下にあるソースコードをコンテナ内の/app/srcに配置するようなNodeJSのアプリを扱う場合に次のように設定したとします。

compose.yaml
version: "3.8"

services:
  my-app:
    container_name: my-app
    build:
      context: .
+   develop:
+     watch:
+       - action: sync
+         path: ./src
+         target: /app/src
+       - action: rebuild
+         path: ./package.json  
    tty: true
    volumes:
      - ./src:/app/src:cached
    ports:
      - 3000:3000

こうすることで、下記のような動作が発生し、外部ライブラリに頼らずともお手軽にホットリロードが実現できます!

  • ./src以下が更新された時、コンテナ内の/app/src以下のファイル・ディレクトリが手元の./src以下のファイル・ディレクトリに置き換わる
  • package.jsonが更新された時、自動でコンテナが再ビルドされる

コンパイル型言語

例えばライブラリを用いずにGolangでホットリロードを実現したい場合に次のように設定したとします。

compose.yaml
version: "3.8"

services:
  my-app:
    container_name: my-app
    build:
      context: .
+   develop:
+     watch:
+       - action: rebuild
+         path: .
    tty: true
    ports:
      - 3000:3000

このようにすると、ソースコードだけでなくgo.modなどのファイルが更新された際も、自動でコンテナが再ビルドされ、ホットリロードが実現できます!

え、でも不要なファイルの変更まで検知されるのはちょっと。。。 → ignoreオプションもあります!

タイトルの通り、ignoreオプションで検知に検知に使用したくないファイルを除外することもできます!
例えば、先ほどのコンパイル型言語の例で、プロジェクトルートにあるREADME.mdの変更を無視したい場合は次のようにします。

compose.yaml
version: "3.8"

services:
  my-app:
    container_name: my-app
    build:
      context: .
+   develop:
+     watch:
+       - action: rebuild
+         path: .
+         ignore:
+           - README.md
    tty: true
    ports:
      - 3000:3000

まとめ

日々ライブラリの管理・更新に悩まされている我々エンジニアにとってDocker Compose Watchのような、インフラレイヤーでホットリロードを可能にする技術が登場したことは大変嬉しいことですね :smile:
皆様もぜひ、Dockerを用いた快適な開発ライフを送ってください :tada:

参考文献

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7