Docker で Go のアプリケーションをホットリロードする環境を構築してみた
https://gyazo.com/f93e6deb916a91570ed5926910ce3c6f
久しぶりに Go で API を作成していて、都度ビルドするのが面倒なので、ホットリロードしてくれる環境を作ろうとしました。
以前は realize というライブラリを使用していたが、ほとんどメンテナンスされていないようでした。 こちらの記事 を参考に air というライブラリを試してみました。 使い方は realize 同様、設定ファイル一つ用意すれば簡単でした。
使ってみる
まずは Dockerfile を作成します。
air 公式でも専用のイメージがあるようなので、そちらを使用しても良いかと思います。
code:Dockerfile
FROM golang:1.16-alpine
RUN mkdir /mydir
WORKDIR /mydir
COPY ./go.mod .
COPY ./go.sum .
RUN go mod download
RUN go get -u github.com/cosmtrek/air
COPY . .
EXPOSE 8000
これでビルドしたイメージを使います。
設定ファイルは公式リポジトリに存在しているものをコピーして使用します。
コメントが記載されているので分かりやすいです。
重要なのは、 cmd と bin で、それぞれビルドコマンドと実行バイナリです。
出力先を合わせておく必要があります。
Docker を使っている場合、停止信号が送られると、一時ファイル内のファイルは削除してくれます。
これだけでホットリロードをしてくれます。
本筋とは関係ないが詰まったこと
導入時、初回のビルドはうまく行くのですが、 2 回目以降のビルドが終了せず、リロードされない状態になりました。
(ハングアップしてる感じ)
ライブラリというか Docker の問題な気はしたので、色々ググったり試してみましたが、長時間解決策が見出せませんでした。
メモリや CPU は際立って高く使用されているわけではなさそうだったので I/O の方の問題かなぁと勘ぐっていたところ、 Docker の設定で以下の Use gRPC FUSE for file sharing にチェックが入っていませんでした。
https://gyazo.com/fd2db67d1117c79afbce6fbd1991f5da
以前こちらの記事で、ファイルを gRPC にするとうまくいかなかったのでオフにした気がします。
再度チェックを入れたところ、ビルドから再起動までされるようになりました。
根本的な原因についてはよく分かっていないです。