LoginSignup
10
3

More than 1 year has passed since last update.

GoのHOTリロード機能(air)付きコンテナの環境構築

Last updated at Posted at 2021-11-03

Goはコンパイラ言語なのでgo buildでコンパイルが必要だが、パッケージを導入することでフロントエンドの yarn run watchみたいなHOTリロードができるらしい。

調べてみたところ、realiseは2018年以降メンテされてない様子。。。
最近はメンテナンスが続いてるairの方が導入事例が多いようなので、air導入済みのgo環境をを作ってみました。

作成する環境

  • Go v1.19
  • air v.1.40.4

2022年10月末時点ではGoの最新版はv1.19です。
airもv1.19に対応しているため、最新版の環境を構築します。

今回作成した環境のリポジトリ

手順は省略してHOTリロードするとこまでいきたい場合

下記のコマンドを上から順に実行すればOKです。

git clone https://github.com/hiro-lapis/go-docker && cd go-docker && docker compose up -d --build
docker exec -it go-docker-go-1 ash
air -c .air.toml

ファイル構成

最終的なファイル構成は以下のとおりです。

src
│
├── app
│   ├── .air.toml
│   └── main.go
├── go.mod
├── Dockerfile
└── docker-compose.yml

はじめにdocker-compose.ymlDockerfileを作成し、
次いでgo.mod.air.tomlmain.goを用意します。

手順

step1 go.mod作成

go.modは、go組み込みのmodule管理ファイルです。
アプリケーションはさまざまな部品同士を組み立ててシステムを構成していますが、その部品の依存関係を解決しているのがgo modです。

airを使うのにもgo.modが必要なので、作成します。
その後、appディレクトリを作成し、main.goを作りましょう。

go.modの置き場所は色々やりようがあるみたいですが、プロジェクトのrootディレクトリ(今回でいえばsrcディレクトリ内)が一番よかろうと判断しておいてあります。

go.mod
module go_docker

go 1.19

step2 docker-compose.ymlの作成

こちらもsrc内にて作成。
最低限の記述で記載します。

version: "3"
services:
    go:
        build: .
        tty: true
        ports:
            - "8080:8080"
        volumes:
            - ./app:/go/src/app

ttyについては↓が詳しいです。

また、フロントエンドやDB用のコンテナ含め作成したい時は、以下資料等を参考にするといいかも
dockerでSPAなgin + vue + mysqlの環境をさくっと作った話

step3 Dockerfileの作成

こちらを作り終えたら、src直下で作成するファイルは準備完了です。

FROM golang:1.19.2-alpine3.16

ENV GOPATH /go
ENV GO111MODULE on
RUN mkdir ${ROOT}

RUN apk update && \
    apk --no-cache add git

RUN mkdir ${ROOT}
WORKDIR ${ROOT}

ADD . ${ROOT}

RUN go mod tidy && \
    go install github.com/cosmtrek/air@v1.40.4

CMD ["air", "-c", ".air.toml"]
各記述の意味

go mod tidyでairを入れる準備をした上でインストール
go getは非推奨になっているので、go installを使って、バージョン指定してインストールしています。

その他、各記述の意味については↓がわかりやすいです。

step4 サンプルgoプログラムを作成

appディレクトリ内にgoのコードを作っていきましょう。
まずはHOTリロードでコンパイルされるgoプログラムを作ります。

main.go
package main

import "fmt"

func main() {
	fmt.Println("Hello golang from docker!")
}

step5 air.tomlの作成・編集

この時点でgoとdocker周りの記述はできたので、コンテナを起動してみます。

Dockdrfile内で実行されるairコマンドの実行のために必要な.air.tomlがないためエラーが発生しているので、.air.tomlを作成します。

↓公式リポジトリから.air.tomlのテンプレートをコピー、
app配下に.air.tomlを作りましょう。

step6 コンテナの起動(HOTリロードできていることの確認)

再度コンテナを起動してみます。

docker compose up

image.png

コンパイル&実行されました!
コンパイル後のバイナリはapp/tmp配下に置かれています。

さらに、Printlの内容を少し変更してsaveしてみます。

main.go
func main() {
	fmt.Println("Hello golang from docker!")
}
// ↓変更
func main() {
	fmt.Println("Hello golang from docker with air!")
}

saveと同時に再コンパイルされました!

image.png

バックグラウンドで起動するdocker compose up -dで立てたコンテナに入って実行することもできます。
image.png

その他注意点

構築時にファイル構成、具体的にはgo.mod.air.tomlを置く場所には気をつけましょう。

1. ワーキングディレクトリに.air.tomlを配置する
2. go.modとDockerfileと同じrootディレクトリに配置する

1については、ワーキングディレクトリに.air.tomlがない時にairを実行すると、以下のようなエラーログが出力されます。

 2021/10/30 12:09:04 open .air.toml: no such file or directory

2については、↓go.modが.air.tomlと異なる階層にある状態でairを実行すると、以下のようなエラーログが出力されます。

go_1  | go: go.mod file not found in current directory or any parent directory; see 'go help modules'
go_1  | failed to build, error: exit status 1

参考資料

【Go言語】ホットリロード可能なHTTPサーバのDocker環境構築手順
Go+gin+Air環境をDockerで構築
【Golang/Go言語】Goのホットリロードライブラリをrealizeからairに移行しました
go.modってどこにおくのがいいのだろう

10
3
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
10
3