如何使用 vgo 和给定的 go.mod 下载所有依赖项?
How to download all dependencies with vgo and a given go.mod?
我正在开发一个 go 项目,使用 vgo 和 Dockerfile,我想 docker 缓存项目的依赖项,使其具有两个属性:
- 如果
go.mod
文件发生变化,依赖会重新下载
- 如果我更改了包中的文件,但没有更改
go.mod
,则不会重新下载依赖项。
现在,我这样做:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
但是如果你改变一个go文件,docker文件将不得不从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 容器中,但是会有很多我不需要的文件
- 我可以在构建 docker 容器之前
vgo mod -vendor
复制 vendor 目录,但这依赖于开发人员每次都记住 运行 vgo mod -vendor
go.mod
更改,否则应用程序将无法构建,他们必须 运行 vgo mod -vendor
在重试 docker 构建之前。
你能想出一种方法让我获得像我想象中的 vgo install_dependencies
那样的行为吗?我是否缺少这样做的 vgo 技巧?
我有一个完全相同的问题,想要 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
tl;dr:在当前的 go master 和未来的 go 版本中,go mod download
将完成这项工作。现在你需要一个技巧。
在 gophers slack 上,我提到了这个问题: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 download
,它将在 go
的下一个版本中可用,允许我删除上面愚蠢的 go list
hack。
更新:go mod download
现已广泛可用,您应该在 go 1.12 及更高版本上使用它
我正在开发一个 go 项目,使用 vgo 和 Dockerfile,我想 docker 缓存项目的依赖项,使其具有两个属性:
- 如果
go.mod
文件发生变化,依赖会重新下载 - 如果我更改了包中的文件,但没有更改
go.mod
,则不会重新下载依赖项。
现在,我这样做:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
但是如果你改变一个go文件,docker文件将不得不从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 容器中,但是会有很多我不需要的文件 - 我可以在构建 docker 容器之前
vgo mod -vendor
复制 vendor 目录,但这依赖于开发人员每次都记住 运行vgo mod -vendor
go.mod
更改,否则应用程序将无法构建,他们必须 运行vgo mod -vendor
在重试 docker 构建之前。
你能想出一种方法让我获得像我想象中的 vgo install_dependencies
那样的行为吗?我是否缺少这样做的 vgo 技巧?
我有一个完全相同的问题,想要 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
tl;dr:在当前的 go master 和未来的 go 版本中,go mod download
将完成这项工作。现在你需要一个技巧。
在 gophers slack 上,我提到了这个问题: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 download
,它将在 go
的下一个版本中可用,允许我删除上面愚蠢的 go list
hack。
更新:go mod download
现已广泛可用,您应该在 go 1.12 及更高版本上使用它