我正在使用vgo和一个Dockerfile开展一个go项目,我希望docker能够缓存项目的依赖项,这样它就有两个属性:
>如果go.mod文件发生更改,则将重新下载依赖项
>如果我更改了包中的文件,但没有更改go.mod,则不会重新下载依赖项.
现在,我这样做:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
但是如果你改变一个go文件,就必须从COPY层开始重建dockerfile.
简而言之,我想做的是:
...
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容器中,但是这将有很多我不需要的文件
>我可以在构建docker容器之前vgo mod -vendor,并复制供应商目录,但这依赖于开发人员每次go.mod更改时都记得运行vgo mod -vendor,否则应用程序将无法构建在重试docker build之前,他们必须运行vgo mod -vendor.
你能想到一种方法让我获得像我想象中的vgo install_dependencies这样的行为吗?我错过了一个vgo技巧吗?
最佳答案
tl; dr:在当前go master和将来的go版本中,去mod下载将完成这项工作.现在你需要一个黑客.
关于gophers的松弛,我被提到这个问题:https://github.com/golang/go/issues/26610,我知道这会或多或少地做我想要的(假设你在使用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下载,将在下一个版本的go中提供,允许我删除上面的愚蠢的go list list.