げっとシステムログ

WEB開発メモ

golang でクロスコンパイルする話

CONTENTS
  1. やりたいこと
  2. できたやつ
  3. CGO_ENABLED
  4. GOOS と GOARCH
  5. まとめ
  6. 参考資料
ENVIRONMENTS
  • golang : 1.14.4

やりたいこと

go build の結果だけを含んだ Docker Image を作りたい。 このためには CGO_ENABLED を無効にする必要がある。

TOP

できたやつ

以下の Dockerfile をビルドする。

FROM golang:1.14.4-buster as builder
COPY . /build
WORKDIR /build
RUN : && \
  CGO_ENABLED=0 \
  GOOS=linux \
  GOARCH=amd64 \
  go build -a -o app . && \
  :

FROM scratch
COPY --from=builder /build/app /app
CMD ["/app"]

使用する golang のイメージは適宜指定する。 また、GOOSGOARCH はデプロイするノードの環境と合わせる。

TOP

CGO_ENABLED

雑な理解では、これはコンパイル時にシステム native な C ライブラリの使用を指定するもの。 クロスコンパイルを行うときは自動的に無効となる、とドキュメントに書いてある。

native なライブラリとリンクすることになるので、実行時に「なんか起動できない」っていうエラーになる。 実際に出たエラーメッセージは以下の通り。

standard_init_linux.go:211: exec user process caused "no such file or directory"

TOP

GOOS と GOARCH

クロスコンパイルするための OS とアーキテクチャの指定。 何を指定するかはこの記事を参考にした。 最新のリストはソースを見るとわかる。

これは実際に動かすマシンのものを指定する。 今回は GKE の「コンテナ用に最適化された OS(cos)」で動かすので、GOOS=linuxGOARCH=amd64 を指定した。

TOP

まとめ

go build を scratch に置いてデプロイするための Dockerfile についてまとめた。

「なんか実行できない」っていう例のエラーから CGO_ENABLED にたどり着くのまで結構な時間がかかってしまったが、何とかデプロイまでたどり着けたのでヨシとする。

TOP

参考資料

TOP