私はvgoを使用してDockerfileでgoプロジェクトに取り組んでいます。dockerがプロジェクトの依存関係をキャッシュして、2つのプロパティを持つようにしたいと思います。
go.mod
ファイルが変更され、依存関係が再ダウンロードされますgo.mod
、依存関係は再ダウンロードされません。今、私はします:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
しかし、goファイルを変更した場合、dockerfileはCOPY
レイヤーから再構築する必要があります。
要するに、私がしたいことは:
...
RUN go get -u golang.org/x/vgo
COPY go.mod /go/src/whatever
RUN vgo install_dependencies
COPY . /go/src/whatever
RUN vgo install
...
そうすれば、go.mod
、すべての依存関係がダウンロードされて再構築されますが、それ以外の場合は、バイナリの構築に進むことができます。
このような動作を得る方法はいくつかありますが、それらにはすべて欠点があります。
$GOPATH/src/mod
をdockerコンテナーに入れますが、必要のないファイルがたくさん含まれます。vgo mod -vendor
dockerコンテナを構築してベンダーディレクトリをコピーする前に、開発者がvgo mod -vendor
毎回go.mod
変更。それ以外の場合、アプリはビルドされず、実行する必要がありますvgo mod -vendor
dockerビルドを再試行する前。私の想像上の行動を得る方法を考えていただけませんかvgo install_dependencies
?これを行うためのvgoトリックがありませんか?
tl; dr:現在のgoマスターおよび今後のgoリリースでは、go mod download
がこの作業を行います。今のところ、ハックが必要です。
Gophers slackで、私はこの問題を参照しました: https://github.com/golang/go/issues/2661 これは私が望むことを多少なりとも実行することを学びました(ここで仮定します) goバージョン1.11beta3を使用していること):
# Populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .
RUN go list -e $(go list -f '{{.Path}}' -m all)
スレッドの後半で、Russ Coxはgo mod download
を実装します。これはgo
の次のリリースで使用可能になるため、上記のばかげたgo list
ハックを削除できます。
更新:go mod download
が広く利用可能になり、1.12以降で使用する必要があります
私はまったく同じ問題を抱えており、Dockerキャッシングをより正確にしたいと思っていました。
だから私はそのための独自のツールを書いたところです https://github.com/gladkikhartem/gomodget
これで、私のdocker-in-dockerパイプラインはわずか10秒になり、dockerビルドログは次のようになります。
Step 4/15 : RUN go get -u golang.org/x/vgo
---> Using cache
---> 12c672a07a16
Step 5/15 : RUN go get github.com/gladkikhartem/gomodget
---> Using cache
---> acc70fea0edc
Step 7/15 : COPY go.mod .
---> Using cache
---> 41bae1ca7428
Step 8/15 : RUN gomodget
---> Using cache
---> 758100f7dde2
Step 9/15 : COPY . .
---> cc833c5bc810
Step 10/15 : RUN vgo build -ldflags '-extldflags "-static"' -o /bin/app