0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker 環境で Air を使ったホットリロード時の「main: not found」エラーの解決方法

Posted at

はじめに

今回は、Docker コンテナ上で Go の開発環境を構築し、Air を利用してホットリロードを実現していた際に発生したトラブルシューティングの内容をまとめました。
最終的に、Air の設定を修正することでエラー「/bin/sh: 1: main: not found」が解消し、正常にサーバーが起動するようになりました。

環境構成

以下のようなツリー構造でプロジェクトを構成しています。

.
├── api
│   ├── cmd
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── .air.toml
│   ├── docker
│   │   └── Dockerfile         # 本番用 Dockerfile
│   └── docker.dev
│       └── Dockerfile         # 開発用 (Air 利用) Dockerfile
├── app
│   ├── src                   # フロントエンドのソースコードなど
│   └── docker
│       └── nginx
│           └── default.conf
└── docker-compose.yml

docker-compose.yml では、api サービスは ./api をコンテキストとして、docker.dev/Dockerfile を使ってビルドしています。また、ホストの ./api/cmd をコンテナ内の /app に volume マウントしており、Air を起動する構成になっています。

発生したエラー

開発用 Dockerfile(api/docker.dev/Dockerfile)では以下のように Air を起動しています。

...
EXPOSE 8080
CMD ["air"]

しかし、コンテナのログを見ると以下のようなエラーが発生していました。

[06:41:11] running...
/bin/sh: 1: main: not found
...
[06:41:57] running...
[06:41:57] Process Exit with Code: 127
/bin/sh: 1: main: not found

また、コンテナ内で netstat コマンドを使ってもポート 8080 で待ち受けしているプロセスは確認できませんでした。

エラー原因

Air は、.air.toml の設定に基づいてアプリケーションをビルドし、生成されたバイナリを起動しようとします。
今回、.air.toml の設定で bin および full_bin"main" と指定していたため、Air はカレントディレクトリ内から main というコマンドを探していました。

しかし、Linux ではカレントディレクトリは PATH に含まれていないため、実行ファイルを起動するには ./main と明示的に指定する必要があります。その結果、Air はビルドに成功しても、実行時に main を見つけられずエラーが発生していました。

解決方法

1. .air.toml の修正

.air.toml の設定ファイルを下記のように修正しました。

[build]
cmd = "go build -o main ."
bin = "./main"
full_bin = "./main"

[log]
time = true

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

これにより、Air は ./main としてバイナリを実行するため、正しく起動できるようになりました。

2. 補足:PATH の設定変更(別案)

別の解決策として、Dockerfile 内でカレントディレクトリを PATH に追加する方法も考えられます。
例えば、以下のように環境変数を設定すれば、main を直接実行できるようになります。

ENV PATH="/app:${PATH}"

ただし、今回は Air の設定を修正するほうがシンプルで分かりやすかったため、この方法は採用しませんでした。

結果

修正後、Air のログにはビルドと実行が正常に行われた旨のメッセージが表示され、コンテナ内で ss -tln コマンドで確認したところ、0.0.0.0:8080 でサーバーが待ち受ける状態になりました。
これにより、ホストから localhost:8080 へアクセスすると正しくレスポンスが返却されるようになりました。

まとめ

  • エラーの原因
    • Air の設定で実行するバイナリのパスが "main" となっており、PATH にカレントディレクトリが含まれていないため、実行できなかった。
  • 解決策
    • .air.tomlbinfull_bin./main に変更することで、ビルドしたバイナリを正しく実行できるようにした。
  • 補足
    • Docker コンテナ内ではサーバーが外部アクセス可能になるよう、Go のサーバーコードで http.ListenAndServe("0.0.0.0:8080", handler) とする必要がある点にも注意する。

今回のトラブルシューティングを通して、Air の設定や Docker コンテナ内での実行環境について改めて理解を深めることができました。
皆さんの開発環境構築の参考になれば幸いです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?