2
1

More than 1 year has passed since last update.

[Go言語] Airを使って最短でホットリロードを実現する

Last updated at Posted at 2021-12-05

環境

以下の実行環境で動作を確認しています。

$ go version
go version go1.15.4 darwin/amd64
$ docker -v
Docker version 20.10.10, build b485636
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

ホットリロードのライブラリといえば色々ありますが・・・

最近ではAirが1番流行っているようです。サクッと試してみます。

スクリーンショット 2021-12-05 23.31.36.png
Star History

必要なファイルを作成する

以下のファイルが必要になります。

$ tree
.
├── Dockerfile
├── air.toml
├── docker-compose.yml
├── go.mod
└── server.go

シンプルなAPIサーバーを作成する

リクエストを行うと「Hello, World」とレスポンスをするシンプルなAPIサーバーを作成します。

server.go
package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Dockerfileを作成する

Dockerfileを作成します。Golang - Official Image | Docker Hub に記述されているものに少し手を加えています。

Dockerfile
FROM golang:1.17

WORKDIR /go/src/app
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

RUN go get -u github.com/cosmtrek/air

CMD ["air"]

docker-compose.yml

docker-compose.ymlを作成します。

docker-compose.yml
version: "3"
services:
  go:
    build: .
    volumes:
      - ./:/go/src/app
    ports:
      - "8080:8080"

air.tomlを作成する

Airのリポジトリ に公開されている設定ファイルを使わせてもらいます。

air.toml
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format

# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o ./tmp/main ."
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary, can setup environment variables when run your app.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true

go.modを作成する

ターミナルで以下のコマンドを実行します。

$ go mod init air-sample

実行する

以下のコマンドを実行します。 running...と表示され動作していることを確認しました。

$ docker-compose up --build
...
go_1  | 
go_1  |   __    _   ___  
go_1  |  / /\  | | | |_) 
go_1  | /_/--\ |_| |_| \_ , built with Go 
go_1  | 
go_1  | watching .
go_1  | !exclude tmp
go_1  | building...
go_1  | running...

別のターミナルをからAPIリクエストを実行してみて、レスポンスが返ってくることを確認します。

$ curl http://localhost:8080
Hello, World

次に、server.goの内容を変更します。
出力を「Hello, Gopher」に変更し、保存します。

server.go
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, Gopher")
}

ファイルの変更を検知してビルド走ります。

go_1  | server.go has changed
go_1  | building...
go_1  | running...

もう一度、APIリクエストを行うとレスポンスが変化していることがわかります。

$ curl http://localhost:8080
Hello, Gopher

以上です。

参考

cosmtrek/air: ☁️ Live reload for Go apps
【Golang】 Airを用いてWebアプリケーション開発中に変更を即座に反映する - zuckey blog
Golang - Official Image | Docker Hub

2
1
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
2
1