我想在需要使用 Docker 的 CI 环境中测试我的 Go 代码。如何创建具有 go.mod
中列出的所有依赖项的 Docker 镜像已下载并编译,以便 docker run $IMG go test
使用缓存的工件?
此图像的所需属性:
go.mod
编译依赖项。我不想使用完整的源代码,因为对源代码的任何更改都会使包含缓存依赖项的 Docker 层失效。 docker run $IMG go test ./...
不会重新下载或重新编译 go.mod
中列出的依赖项. 现有方法
解析 go.mod 并使用 go get
来自 https://github.com/golang/go/issues/27719#issuecomment-578246826
这种方法很接近,但似乎没有使用
GOCACHE
当我运行 go test
.这似乎也会在某些模块路径上阻塞,例如 gopkg.in/DataDog/dd-trace-go.v1
:FROM golang:1.13
WORKDIR /src
COPY go.mod ./
RUN set -eu \
&& go mod graph \
| cut -d '@' -f 1 \
| cut -d ' ' -f 2 \
| sort -u \
| sed -e 's#dd-trace-go.v1#&/ddtrace#' \
| xargs go get -v
docker run --mount /src:/src $IMG go test ./...
使用带有装载缓存的 DOCKER_BUILDKIT
最初在 https://github.com/golang/go/issues/27719#issuecomment-514747274 中描述.这仅适用于
go build
.我不能用它来 go test
因为缓存挂载在 RUN 命令之后被卸载,所以它在创建的 Docker 镜像中不存在。这也取决于实验性 docker 功能。
# syntax = docker/dockerfile:experimental
FROM golang:1.13 as go-builder
ARG VERSION
WORKDIR /src
COPY . /src/
# With a mount cache, Docker will cache the target directories for future
# invocations of this RUN layer. Meaning, once this command is run once, all
# successive calls will use the already downloaded and already compiled assets.
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build ./server
最佳答案
我经常放COPY go.mod
在 Dockerfile 的最开始,因为它不会经常更改。
FROM golang:1.14.3 as builder
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
RUN go build -tags netgo -ldflags '-extldflags "-static"' -o app .
FROM centos:7
WORKDIR /root
COPY --from=builder /app/app .
所以,如果你去 mod 没有改变,行 RUN go mod download
只运行第一次。
关于docker - 创建 docker 容器以运行 `go test` 并下载并缓存所有模块依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60200363/