docker - 创建 docker 容器以运行 `go test` 并下载并缓存所有模块依赖项

标签 docker go

我想在需要使用 Docker 的 CI 环境中测试我的 Go 代码。如何创建具有 go.mod 中列出的所有依赖项的 Docker 镜像已下载并编译,以便 docker run $IMG go test使用缓存的工件?

此图像的所需属性:

  • 图片仅使用go.mod编译依赖项。我不想使用完整的源代码,因为对源代码的任何更改都会使包含缓存依赖项的 Docker 层失效。
  • docker run $IMG go test ./...不会重新下载或重新编译 go.mod 中列出的依赖项.
  • 避免实验性的 Docker 功能。

  • 现有方法

    解析 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/

    相关文章:

    docker - map 下载失败 : Invalid key or download temporarily unavailable

    docker - Docker-compose容器:如何为端口别名?

    go - 指针的行为

    go - 是否可以从 Visual Studio Code 调试 go revel 框架?

    Golang二叉搜索树算法翻译

    logging - 将日志元数据写入 rsyslog

    docker - 将日志从Docker容器保存到Windows文件系统

    go - 如何让每个眼镜蛇命令解析自己的标志?获取初始化循环(预期,但如何避免?)

    types - Go - math.MaxInt64 和类型推断错误

    apache - 配置 apache2 和主机以使用 nginx 将流量传递到 docker 容器