はじめに
この記事はローカルの開発環境でコンテナを用いている人に向けた開発効率化を目的としたものです。
dockerのようなコンテナ技術を用いてローカル開発を行うことにはさまざまなメリットがあります。例えば
- 開発環境の共通化
- 開発環境構築の難易度軽減
- ローカルマシンをクリーンに保てる
などです。
しかし、同様にいくつかの課題も存在し、その中の一つとして工夫しないとホットリロードができない、というものがあります😭
今回はその「工夫しないとホットリロードができない」を簡単に解決してくれる機能であるDocker Compose Watch
を紹介したいと思います!
従来のコンテナを用いたホットリロードな開発環境
インタープリタ型言語
JavaScriptなどのインタープリタ型言語では再ビルドの必要がないため、次のようにソースコードが格納されたディレクトリを丸ごとコンテナにマウントするケースが多かったかと思います。
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
の更新が入った場合はコンテナをビルドし直す、といった方針を取られていた方も多いのではないでしょうか
コンパイル型言語(or JVM系言語)
Goなどのコンパイル言語は基本的にはコンパイルし直さないとソースコードの変更がアプリに反映されないため、ソースコードを変更するたびに再ビルド、あるいはライブラリなどでホットリロードを可能にした上でコンテナ内部に入って開発する、といったことが多かったかと思います。
しかし、ソースコードの更新のたびにコンテナを手動でビルドし直すのは手間です。また、ホットリロードを有効化してコンテナ内部で開発を行うのにはコンテナ内部での開発が快適に行えるような専用の環境やIDE側でのセットアップが必要であり、すでに環境が整っているようなケースを除いては準備が手間ですし、環境構築の難易度も高くなってしまいがちです
そこでDocker Compose Watch
の出番です。
Docker Compose Watch
とは?
Docker Compose Watch
とは、Docker Compose
に内蔵されている機能の一つでローカルファイルの変更を検知し、コンテナ内部のファイルを置き換えたり、コンテナを再ビルドしてくれる機能です。
compose.yaml
or docker-compose.yaml
に規定の項目を書いた上で
docker compose watch
のコマンドを実行することで使用できます!
Docker Compose Watch
にはsync
とrebuild
の二つの機能があり、それぞれ
- syncは追跡中のローカルのファイルに変更が生じたら、自動で実行中のコンテナ内のファイルを設定通りに置き換える
- rebuildは追跡中のローカルのファイルに変更が生じたら、自動でコンテナを再ビルドする
といった機能となっています!
下記で例を見てみましょう!
Docker Compose Watch
を用いたホットリロードな開発環境
インタープリタ型言語
例えばpackage.jsonをプロジェクトルートディレクトリに含み、./src
以下にあるソースコードをコンテナ内の/app/src
に配置するようなNodeJSのアプリを扱う場合に次のように設定したとします。
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でホットリロードを実現したい場合に次のように設定したとします。
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
の変更を無視したい場合は次のようにします。
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
のような、インフラレイヤーでホットリロードを可能にする技術が登場したことは大変嬉しいことですね
皆様もぜひ、Dockerを用いた快適な開発ライフを送ってください
参考文献