はじめに
M1 Mac上でDockerコンテナにdelveやAirをインストールしたところ、$GOPATH/bin
下に実行バイナリが作成されなかった。
結論
$GOPATH/ └── bin/ └── $GOOS_$GOARCH/ └── dlv
クロスコンパイルされていたことで、$GOPATH/bin
でなく$GOPATH/bin/$GOOS_$GOARCH
下に実行バイナリが作成されていた。
go install
前に環境変数GOOS
、GOARCH
をexportしていたために起きており、実行順序を変更して解決した。
事象
M1 Mac上で、たとえば下記のようなDockerfileに基づき、docker-compose
を使ってDocker Imageのビルドを試みたとする。
FROM deps AS development # クロスコンパイルのための環境変数 ENV CGO_ENABLED=0 ENV GOOS=linux ENV GOARCH=amd64 WORKDIR /tmp/hoge/app RUN go install github.com/go-delve/delve/cmd/dlv@latest … RUN go build -mod=mod -o /app -gcflags="all=-N -l"
すると、下記のようなErrorが出てビルドに失敗する。
この場合、delveの実行バイナリが$GOPATH/bin
配下に無いと怒られた。
ERROR: for hoge-app_1 Cannot start service hoge-app: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/go/bin/dlv": stat /go/bin/dlv: no such file or directory: unknown
docker-compose
を定義するYAML内で下記のようにdelveを呼び出しているためである。
command: dlv exec /app --listen=:13100 --headless --api-version=2 --continue --accept-multiclient -hoge-api
調査
方針
件の実行バイナリの行方を追った。
$ go install github.com/go-delve/delve/cmd/dlv@latest
の結果、実行バイナリは$GOPATH/bin
以外のどこかにいるのか、あるいはいないのか。
手順
一手目
上述のDockerfile内で指定していた、構築したいGo環境と同versionのOfficial Image Simple tagを利用してDockerコンテナを立ち上げる。
今回はgolang:1.16.6
を指定。コンテナ内に入る。
$ docker run -it golang:1.16.6 /bin/sh
ここからはDockerfileの実行順に従う。 まず、コンテナ内で下記の環境変数を指定。
$ export CGO_ENABLED=0 $ export GOOS=linux $ export GOARCH=amd64
次に、go install
で任意のパッケージ(ここではdelve)をインストールする。
$ go install github.com/go-delve/delve/cmd/dlv@latest
ここで$GOPATH/bin
配下を確認すると、delveの実行バイナリであるdlv
ファイルでなく、linux_amd64
なるディレクトリが作成されていた。
そして、linux_amd64
の配下にdlv
ファイルが格納されていた。
二手目
dlv
ファイルは存在していた。ただし$GOPATH/bin
配下ではなかった。
そこで、再度Goコンテナを立ち上げ、今度は環境変数GOOS
とGOARCH
をexportする前に、任意のパッケージ(ここではdelve)をgo install
した。
すると、今度は$GOPATH/bin
配下にdlv
ファイルが作成されていることを確認できた。
先に確認した$GOOS_$GOARCH
からなるディレクトリは、環境変数GOOS
、GOARCH
を設定すると作成され、以降go install
したパッケージの実行バイナリはその配下に格納されるようだ。
まだ分かっていないこと
本事象の確認環境についてM1 Macと明記したのは、筆者の周囲で本事象が再現したのはM1 Macユーザーのみだったからだ。
IntelモデルのMacを使用しているユーザーの環境では、パッケージインストール前にGOOS
とGOARCH
を指定しても$GOOS_$GOARCH
ディレクトリは切られず、$GOPATH/bin
直下に実行バイナリが作成されていた。
この差異については本校執筆時点で未調査のため、原因が分かれば追って記載する。