使用go.mod将构建的模块下载到GOBIN以进行Docker缓存。

huangapple go评论84阅读模式
英文:

Download built modules to GOBIN using go.mod for Docker caching

问题

我有一个多阶段的Dockerfile(使用BuildKit),其中包含一个初始阶段,用于go get我需要在后续阶段中使用的几个工具作为二进制文件。
以下示例是其要点:

# syntax = docker/dockerfile:1.0-experimental
# Go build stage
FROM golang:1.14-alpine3.12 AS gobuild
RUN apk add --no-cache git

RUN GO111MODULE=on go get -v github.com/tool1/tool1
RUN GO111MODULE=on go get -v github.com/tool2/tool2
RUN GO111MODULE=on go get -v github.com/tool3/tool3

# ...

# Release stage
FROM base AS release

# Copy Go binaries
COPY --from=gobuild /go/bin/tool1 /usr/local/bin/tool1
COPY --from=gobuild /go/bin/tool2 /usr/local/bin/tool2
COPY --from=gobuild /go/bin/tool3 /usr/local/bin/tool3

# ...

这个方法很有效。我唯一的问题是每次docker build都需要重新下载Go Modules,也就是说它们没有被缓存。

经过一些研究,我了解到go mod download可以根据go.mod将Go Modules缓存到本地。

对我来说,go.mod文件是一个很好的解决方案,因为它指定了确切的模块版本;所以在使用Docker时,缓存会更简单,因为可以重用层,除非go.mod发生了变化。

我通过运行go mod init github.com/me/myproject来轻松实现这一点,然后后续的go get调用会将相关模块添加到go.mod中。

但是我缺少最后一步,类似于go mod download但具有与go get相同的“输出”,它将构建的二进制文件保存到GOBIN中。

只是为了澄清,我使用的是用Go构建的工具的二进制文件,但我的项目本身不是一个Go应用程序,它只是使用这些工具。

英文:

I have a multi-stage Dockerfile (uisng BuildKit) which contains an initial stage to go get several tools that I need to use as binaries in a later stage.
The following example is the gist of it:

# syntax = docker/dockerfile:1.0-experimental
# Go build stage
FROM golang:1.14-alpine3.12 AS gobuild
RUN apk add --no-cache git

RUN GO111MODULE=on go get -v github.com/tool1/tool1
RUN GO111MODULE=on go get -v github.com/tool2/tool2
RUN GO111MODULE=on go get -v github.com/tool3/tool3

# ...

# Release stage
FROM base AS release

# Copy Go binaries
COPY --from=gobuild /go/bin/tool1 /usr/local/bin/tool1
COPY --from=gobuild /go/bin/tool2 /usr/local/bin/tool2
COPY --from=gobuild /go/bin/tool3 /usr/local/bin/tool3

# ...

This works well. The only issue I have is that every docker build requires the Go Modules to be downloaded again, i.e. they aren't cached.

After some research, I read about go mod download which is meant to cache Go Modules locally according to go.mod.

The go.mod file is a good solution for me, in that it states exact module versions; so when using Docker, caching will be much simpler since layers can be re-used unless go.mod has changed.

I easily achieve this by running go mod init github.com/me/myproject and then subsequent go get calls add the relevant modules to go.mod.

But I am missing the final piece, something similar to go mod download but with the same "output" as go get, which saves the built binaries to GOBIN.

Just to clarify, I am using binaries of tools built with Go, but my project itself isn't a Go app, it only makes use of these tools.

答案1

得分: 0

根据评论中的建议,在我的情况下,使用Go 1.16和go install package@version是最佳解决方案。

我的Dockerfile现在如下所示:

# syntax = docker/dockerfile:1.0-experimental
# Go build stage
FROM golang:1.16-alpine3.12 AS gobuild
RUN apk add --no-cache git

RUN go install github.com/tool1/tool1@latest
RUN go install github.com/tool2/tool2@latest
RUN go install github.com/tool3/tool3@v1.0.0

# ...
英文:

As suggested in the comments, using Go 1.16 and go install package@version serves as the best solution in my case.

My Dockerfile now looks like this:

# syntax = docker/dockerfile:1.0-experimental
# Go build stage
FROM golang:1.16-alpine3.12 AS gobuild
RUN apk add --no-cache git

RUN go install github.com/tool1/tool1@latest
RUN go install github.com/tool2/tool2@latest
RUN go install github.com/tool3/tool3@v1.0.0

# ...

huangapple
  • 本文由 发表于 2021年7月29日 21:27:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/68576803.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定