27

我正在使用带有模块支持的 go 1.11。我知道 go 工具现在会在构建/安装时自动安装依赖项。我也明白其中的道理。

我正在使用 docker 来构建我的二进制文件。在许多其他生态系统中,复制依赖项清单(package.json、requirements.txt 等)并将依赖项安装为独立于构建的阶段是很常见的。这利用了 docker 的层缓存,并且使重建速度更快,因为通常代码更改远远超过依赖项更改。

我想知道vgo是否有办法做到这一点?

4

4 回答 4

55

这是一个问题#26610,现在已修复。

所以现在你可以使用:

go mod download

为此,您只需要go.mod/go.sum文件。

例如,以下是缓存多阶段 Docker 构建的方法:(来源)

FROM golang:1.17-alpine as builder
RUN apk --no-cache add ca-certificates git
WORKDIR /build

# Fetch dependencies
COPY go.mod go.sum ./
RUN go mod download

# Build
COPY . ./
RUN CGO_ENABLED=0 go build

# Create final image
FROM alpine
WORKDIR /
COPY --from=builder /build/myapp .
EXPOSE 8080
CMD ["./myapp"]

另请参阅文章Containerize Your Go Developer Environment – Part 2,其中描述了如何利用Go 编译器缓存进一步加快构建速度。

于 2019-06-20T20:15:03.247 回答
22

您可以使用将在主模块的根文件夹中go mod vendor创建一个文件夹的命令,并将所有依赖项复制到其中。vendor在此之后,您可以将-mod=vendor参数传递给 go 工具,然后该vendor文件夹中的依赖项将用于构建/编译/测试您的应用程序。

因此,您可以采取哪些措施来加快构建速度:

  1. 运行go mod vendor命令以获得依赖项的实际版本。
  2. 保存/缓存此vendor文件夹。
  3. 在构建期间,恢复此vendor文件夹,并通过将-mod=vendor参数传递给 go 工具来构建/安装您的应用程序,因此不会下载任何依赖项,但vendor将使用该文件夹的内容。

引自go help mod

模块和供应商

使用模块时,go 命令完全忽略供应商目录。

默认情况下,go 命令通过从源下载模块并使用下载的副本来满足依赖关系(经过验证,如上一节所述)。为了允许与旧版本的 Go 互操作,或者确保用于构建的所有文件一起存储在单个文件树中,'go mod vendor' 在主模块的根目录中创建一个名为 vendor 的目录并将所有文件存储在那里支持主模块中包的构建和测试所需的依赖模块中的包。

要使用主模块的顶级供应商目录构建以满足依赖关系(禁用通常的网络源和本地缓存的使用),请使用“go build -mod=vendor”。请注意,仅使用主模块的顶级供应商目录;其他位置的供应商目录仍然被忽略。

于 2018-09-11T08:21:16.563 回答
2

我想使用 重新下载所有依赖项go mod,这就是我所做的:

  1. 去你的GOROOT
  2. sudo rm -rf pkg/mod/
  3. 转到go.mod文件所在的目录
  4. go mod download
于 2020-10-24T00:51:04.063 回答
0

您可以使用包管理器,其中有很多,例如depglidegovendordep更新,将作为官方依赖管理工具集成到 go 工具链中。

我们还为 go 应用程序制作 docker 镜像,我们使用dind制作这些镜像,我们准备了一个 CI/CD 镜像,其中预装了所有依赖项,以加快构建速度。不过,将所有内容粘合在一起需要一些脚本。

此外,将依赖关系分层可能会导致 docker 镜像的大小变大。我建议尝试多阶段构建,这有助于使图像变得超级精简。

于 2018-09-11T02:12:42.547 回答