这个Docker命令是如何工作的,它创建了一个小的GoLang容器?

huangapple go评论85阅读模式
英文:

How does this Docker command, which makes a small GoLang container, work?

问题

新手使用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容器中生成的二进制文件是如何传送到我的本地文件系统的呢?(例如,为什么我需要将二进制文件复制回镜像中,就像DockerFile的第3行所做的那样?)

英文:

New to docker here. I followed the instructions here to make a slim & trim container for my Go Project. I do not fully understand what it's doing though, hopefully someone can enlighten me.

Specifically there are two steps to generating this docker container.

  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 .

The DockerFile itself just contains

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

I understand (in a broad sense) that the 1st step is compiling the go program and statically linking the C-dependencies (and doing all this inside an unnamed docker container). The 2nd step just generates the docker image according to the instructions in the DockerFile.

What I don't understand is why the first command starts with docker run (why does it need to be run inside a docker container? Why are we not just generating the Go binary outside of it, and then copying it in?)

And if it's being run inside a docker container, how is binary generated in the docker container being dropped on my local machine's file system?(e.g. why do I need to copy the binary back into the image - as it seems to be doing on line 3 of the DockerFile?)

答案1

得分: 2

你实际上使用了两个不同的Docker容器,每个容器都有不同的镜像。第一个容器只在编译期间存在...它使用的是golang:1.8镜像。你所做的是将当前工作目录挂载到该镜像中,并使用镜像中包含的GO版本进行编译。

第二个命令构建了一个使用iron/base镜像作为基础的自定义镜像。然后将你构建的应用程序复制到该镜像中并运行。

英文:

You're actually using 2 different docker containers, each with a different image. The first container is only around during the compilation... it uses the image golang:1.8. What you're doing is mounting your current working directory into that image and compiling it with the version of GO contained in the image.

The second command builds your custom image that uses the iron/base image as its base. You then copy your built application into that image and run it.

答案2

得分: 1

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

  • 它确保始终使用相同的Go版本,
  • 编译在一个始终干净的环境中进行,
  • 构建主机不需要安装Go,或者可以安装不同的版本,

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

然而,这个示例挂载了整个本地GOPATH,破坏了上述目的。依赖项必须对构建容器可用,例如通过vendoring它们。也许作者认为vendoring超出了他的示例范围。

(注意:这应该是一个注释,但是我的声誉不允许这样做)

英文:

Using a golang container to build the binary is usually done for reproducibility of the build process, i.e.:

  • it ensures that always the same Go version is used,
  • compilation takes place in an alway clean environment,
  • and the build host needs no Go installed at all, or can have a different version,

This way, all parts needed to build the "hello" image can be tracked in a version control system.

However, this example mounts the whole local GOPATH, defeating above purpose. Dependencies must be available to the build container, e.g. by vendoring them. Maybe the author considered vendoring out of scope for his example.

(note: this should be a comment, but my reputation does not allow that)

huangapple
  • 本文由 发表于 2017年9月15日 21:47:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/46241146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定