web-dev-qa-db-ja.com

vgoと特定のgo.modですべての依存関係をダウンロードする方法

私はvgoを使用してDockerfileでgoプロジェクトに取り組んでいます。dockerがプロジェクトの依存関係をキャッシュして、2つのプロパティを持つようにしたいと思います。

  1. go.modファイルが変更され、依存関係が再ダウンロードされます
  2. パッケージ内のファイルを変更したが、変更しない場合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、すべての依存関係がダウンロードされて再構築されますが、それ以外の場合は、バイナリの構築に進むことができます。

このような動作を得る方法はいくつかありますが、それらにはすべて欠点があります。

  1. コピーできます$GOPATH/src/modをdockerコンテナーに入れますが、必要のないファイルがたくさん含まれます。
  2. 私はできた vgo mod -vendor dockerコンテナを構築してベンダーディレクトリをコピーする前に、開発者がvgo mod -vendor毎回go.mod変更。それ以外の場合、アプリはビルドされず、実行する必要がありますvgo mod -vendor dockerビルドを再試行する前。

私の想像上の行動を得る方法を考えていただけませんかvgo install_dependencies?これを行うためのvgoトリックがありませんか?

8
llimllib

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以降で使用する必要があります

7
llimllib

私はまったく同じ問題を抱えており、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 
1
Artem Co