这个Docker命令是如何生成一个小GoLang容器的?

docker工人在这里。 我按照这里的说明为我的Go项目制作了一个纤细的装饰容器。 我不完全理解它在做什么,希望有人能够启发我。

具体来说有两个步骤来生成这个docker集装箱。

  1. docker run --rm -it -v "$GOPATH":/gopath -v "$(pwd)":/app -e "GOPATH=/gopath" -w /app golang:1.8 sh -c 'CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags="-s" -o hello'
  2. docker build -t myDockerImageName .

DockerFile本身只包含

 FROM iron/base WORKDIR /app COPY hello /app/ ENTRYPOINT ["./hello"] 

我理解(广义上),第一步是编译go程序并静态链接C依赖关系(并在一个未命名的docker容器中完成所有这些)。 第二步是根据DockerFile中的指令生成docker镜像。

我不明白的是为什么第一个命令是以docker run开始的(为什么它需要在Docker容器中运行?为什么我们不只是生成外部的Go二进制文件,然后复制它?)

如果它在docker容器中运行,Docker容器中的二进制文件如何在我的本地机器的文件系统上被丢弃?(例如,为什么我需要将二进制文件复制回镜像 – 就像它在线做的那样3的DockerFile?)

您实际上使用了2个不同的docker集装箱,每个集装箱都有不同的图像。 第一个容器只在编译期间…它使用图像golang:1.8。 你正在做的是将你当前的工作目录挂载到该图像中,并使用图像中包含的GO版本进行编译。

第二个命令构build了使用铁/基本图像作为其基础的自定义图像。 然后,您将构build的应用程序复制到该映像中并运行它。

使用golang容器来构build二进制文件通常是为了构build过程的可重复性,即:

  • 它确保始终使用相同的Go版本,
  • 编辑发生在一个清洁的环境中,
  • 而构build主机根本不需要安装Go,或者可以有不同的版本,

这样,构build“hello”图像所需的所有部分都可以在版本控制系统中进行跟踪。

但是,这个例子把整个当地的GOPATH都打上了顶,以上的目的。 构build容器必须具有相关性,例如通过销售它们。 也许作者考虑过他的例子的范围。

(注:这应该是一个评论,但我的声誉不允许)