0
0

Goのホットリロードツール (Air) で変更反映時のtcpポート競合を回避する方法

Posted at

環境

Docker: 4.20.1
Nginx: 1.23
Air: 1.45.0

記事の要約

Goのホットリロードツール(Air)による再実行時にtcpポート競合が起きてしまっていた問題をAirの設定ファイルを修正することで解決したという記事。

前提

  • Dockerについてある程度知っている
  • Docker環境でのAirの導入は既に出来ている

目次

背景

Goは(RubyやPHPとは異なり)コンパイル言語であるため、実行中のアプリケーションのソースコードへの変更を反映させるためには実行停止+コンパイル+実行を毎回行う必要がある。
これは明らかに面倒だし効率が悪すぎるということで、この辺りの不満を解決してくれるホットリロードという機能が提供されている(GoではAirというモジュールが主流らしい)。

問題

Go言語での開発においてソースコードを書き換えを勝手に検知してbuild+再実行をしてくれるAirであるが、

# listen tcp :8080: bind: address already in use

というエラーが発生しており、 変更が反映されないこともしばしばあり、とても困っていた。

解決

下記に示す様に、airの設定ファイルである".air.toml"ファイルのdelayを0から50に変更する。

.air.toml
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
  args_bin = []
  bin = "./tmp/main"
  cmd = "go build -o ./tmp/main ."
  delay = 50
  exclude_dir = ["assets", "tmp", "vendor", "testdata"]
  exclude_file = []
  exclude_regex = ["_test.go"]
  exclude_unchanged = false
  follow_symlink = false
  full_bin = ""
  include_dir = []
  include_ext = ["go", "tpl", "tmpl", "html"]
  include_file = []
  kill_delay = "0s"
  log = "build-errors.log"
  poll = false
  poll_interval = 0
  rerun = false
  rerun_delay = 500
  send_interrupt = false
  stop_on_error = false

[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  main_only = false
  time = false

[misc]
  clean_on_exit = false

[screen]
  clear_on_rebuild = false
  keep_scroll = true

終わりに

# listen tcp :8080: bind: address already in use

このエラーが発生する際にはbuildが2回走っており、今までのプロセスがkillされる前に新しいプロセスが走っていた、もしくは変更検出後の再実行が2回走っていたのではないかと思われる。ここでdelayを設定することによって、buildの際に待ち時間が発生することでkillの時間稼ぎ、もしくは変更検出したプロセスがすでに走っていることの判定ができる様になることでもmん大が解決したのかな?と思っている(なぜ治ったのかよくわかっていない)。
もし詳しい理由をご存知の方がいたらぜひコメントよろしくお願いします!

0
0
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
0
0