LoginSignup
3

More than 1 year has passed since last update.

Dockerコンテナ内で面倒なgo buildを実行する

の続き。

概要

今回作成したサービスがopencvなどの環境を作成するのが面倒で、buildするのも一苦労するため、buildについてもdockerの中でやってしまおう、ということで試してみた。

topic

  • opencvやgstreamerなど多くのライブラリが必要
    • 開発環境用docker imageがそのまま使用できそう
  • goライブラリの中に、privateなライブラリが含まれている
    • 上記にアクセスするために、SSH鍵が必要
  • 前段のgo build処理 、通常のdocker buildのマルチステージビルド

Dockerfile

今回作成したDockerfileは以下。

ベースイメージであるghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latestについては、

を参照。(上記からの連続記事です)

# syntax=docker/dockerfile:1.0.0-experimental
FROM ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest as go-build

# set Hoge lib as private
ARG GOPRIVATE=github.com/Hoge

# for gocv
ARG LD_LIBRARY_PATH=/usr/local/lib:/app/lib
# for Hoge
ARG CGO_LDFLAGS="-L/app/lib -lHoge"
# for gocv
ARG PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

# ソースコードを/appにコピー
COPY . /app 
WORKDIR /app

RUN git config --global url."ssh://git@github".insteadOf https://github
RUN --mount=type=ssh go mod tidy
RUN go build -o main ./cmd

FROM ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest

RUN mkdir /app
WORKDIR /app

# 1つ目のステージからバイナリだけコピー
COPY --from=go-build /app/main ./main

CMD ["./main"]

syntax=docker/dockerfile:1.0.0-experimental

go mod tidyするためにホスト側のssh private keyをコンテナ内で使用する必要があった。DockerのBuildKitを使うとコンテナに含まれないようにsecret情報をbuild中にマウントできるという情報があり、使ってみた。
その機能を使うためにDockerfileの先頭にこの一行が必要。

参考

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

known_hostsを作成するおまじない。goライブラリをダウンロードするときにgithub.comが追加されている必要があるため。

RUN git config --global url."ssh://git@github".insteadOf https://github

golangのプライベートライブラリにsshでアクセスするためのおまじない。

RUN --mount=type=ssh go mod tidy

今回の肝。これでローカルホスト側のssh鍵をマウントしている。実際にマウントされる鍵は、docker build実行時に指定する。

Makefile

IMAGE=ghcr.io/my_organization/my_application
TAG=latest

build:
    docker build --ssh default=${HOME}/.ssh/id_rsa -t $(IMAGE) .
    docker tag $(IMAGE) $(IMAGE):$(TAG)
    docker push $(IMAGE):$(TAG)

これで

$ make build

でgo build、docker buildが行われてrepositoryにpushされる。

評価

ssh鍵をdockerコンテナ内で使う方法で悩んだ。BuildKitを使う事で上記はクリアし、シンプルなDockerfile & Makefileになったように思う。

開発環境をそのままビルド環境に利用したことの是非は判断できていない。
開発環境イメージには不要なものもたくさん含まれているとは思うものの、開発環境なら確実にビルドできるだろう、という思いもある。

ビルドに不要なものを.dockerignoreで外すのをお忘れなく!

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
What you can do with signing up
3