docker - Golang 构建所有下载的包

标签 docker go

我正在尝试为我的 go 应用程序构建一个 docker 镜像,并且我想与编译应用程序的源代码分开构建所有包依赖项。

下面是一个可能有用的示例:

FROM ubuntu:focal

# ... a bunch of run commands that install go and other binaries I need

ENV GOPATH=/root/go
WORKDIR gadic

COPY go.mod .
RUN go mod download
RUN go build /root/go/pkg/... # this fails!!

COPY src src
RUN go build path/to/main.go # I'd like to speed this step up by pre-compiling the packages main.go depends on

当我尝试构建此 dockerfile 时,我得到以下输出:

 > [ 8/19] RUN go build /root/go/pkg/...:
#12 0.955 pattern /root/go/pkg/...: directory prefix /root/go/pkg outside available modules

有没有办法在构建我的应用程序的 main.go 之前构建我的应用程序所依赖的包/模块?

最佳答案

您真正需要的是构建缓存,请参阅 this .

需要将两个文件夹安装到构建容器中:

  • GOPATH

    这里我们设置为/root/go,用于存放下载的依赖

  • GOCACHE

    默认为/root/.cache/go-build,用于构建缓存

接下来是一个最小的例子。

Dockerfile:

# syntax = docker/dockerfile:1.2
FROM golang
ENV GOPATH=/root/go
WORKDIR /root
COPY main.go .
COPY go.mod .
COPY go.sum .

RUN --mount=type=cache,mode=0755,target=/root/.cache/go-build --mount=type=cache,mode=0755,target=/root/go go build -v main.go

ma​​in.go:

package main

import (
     _ "github.com/phachon/go-logger"
)

func main() {
}

go.mod:

module trial

go 1.14

require github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea

go.sum:

github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea h1:IkOONr/u7Wy+j2R4r1eMV8PEuN4kmOhZZNaYxDOF+KQ=
github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea/go.mod h1:WBIWFH/iYYvuApCvPU+/R6hfX6v0Ogu4apwf0UgzVF0=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

执行:

  • 第一次,您可以看到它下载依赖包,然后构建不同的包。
$ export DOCKER_BUILDKIT=1
$ docker build --progress=plain -t abc:1 . --no-cache
...
#14 [stage-0 6/6] RUN --mount=type=cache,mode=0755,target=/root/.cache/go-bu...
#14 3.100 go: downloading github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea
#14 3.330 go: downloading github.com/fatih/color v1.7.0
#14 3.331 go: downloading github.com/mailru/easyjson v0.7.0
#14 3.523 go: downloading github.com/mattn/go-colorable v0.1.4
#14 3.561 go: downloading github.com/mattn/go-isatty v0.0.11
#14 3.731 go: downloading golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
#14 5.058 github.com/mailru/easyjson/buffer
#14 5.063 golang.org/x/sys/unix
#14 5.070 github.com/mailru/easyjson/jlexer
#14 5.077 github.com/mailru/easyjson/jwriter
#14 5.087 github.com/phachon/go-logger/utils
#14 5.174 github.com/mailru/easyjson
#14 5.346 github.com/mattn/go-isatty
#14 5.355 github.com/mattn/go-colorable
#14 5.368 github.com/fatih/color
#14 5.396 github.com/phachon/go-logger
#14 5.451 command-line-arguments
#14 DONE 7.4s
...
  • 第二次,我将 main.go 更改为下一个:

ma​​in.go:

package main

import (
     _ "github.com/phachon/go-logger"
     "fmt"
)

func main() {
    fmt.Println("helloworld")
}

然后,再次执行构建:

$ export DOCKER_BUILDKIT=1
$ docker build --progress=plain -t abc:1 . --no-cache
...
#14 [stage-0 6/6] RUN --mount=type=cache,mode=0755,target=/root/.cache/go-bu...
#14 1.469 command-line-arguments
#14 DONE 3.2s
...

从上面可以看到,它不再下载包(因为/root/go 在不同的构建过程中被重用)。并且,它只是构建command-line-arguments,对应于main.go的更改,没有与github.com/phachon/go-logger相关的包 已重建(因为/root/.cache/go-build 作为构建缓存被重用)。

关于docker - Golang 构建所有下载的包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68025858/

相关文章:

node.js - Docker Node JS 安装

go - 在 Revel 应用中读取 "public"文件内容

http - 无法成功实现 http.Handler

go - 所有可能的 GOOS 值?

docker - 如何在多节点集群上的 Kubernetes Pod 中使用 ConfigMap 放置整个目录及其子目录?

python - 如何使 dockerized Flask 应用程序将输出写入文件?

go - GUI 未运行 - 未在 DLL 中找到入口点

go - 在 WebSocket 中获取完整的 URL

Docker compose 端口映射,主机端口 != 容器端口

docker-compose - 如何使用 Docker for Windows 创建 MySQL 数据库?