Я хочу протестировать свой код Go в среде CI, для которой необходимо использовать Docker. Как создать изображение Docker, в котором все зависимости, перечисленные в go.mod
, уже загружены и скомпилированы, чтобы docker run $IMG go test
использовала кэшированные артефакты?
Желаемые свойства этого изображения:
В изображении используется только go.mod
для компиляции зависимостей. Я не хочу использовать полный исходный код, потому что тогда любое изменение исходного кода сделает недействительным слой Docker, который содержит кэшированные зависимости.
docker run $IMG go test ./...
не загружается повторно или Перекомпилируйте зависимости, перечисленные в go.mod
.
Избегайте экспериментальных Docker функций.
Существующие подходы
Синтаксический анализ go .mod и использование go get
From 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