构建用于 Go 程序的 Docker 中的 Docker

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

Building Docker within Docker for Go program

问题

我正在尝试为一个Go程序构建一个非常小的Docker容器。为此,我希望使用一个Docker容器来构建Go程序,然后(在容器内部)构建另一个Docker容器来运行该程序。

这是我的构建Dockerfile:

FROM google/golang
WORKDIR /gopath/src/mycompany/mygoprog

# Build the Contributors application
RUN mkdir -p /gopath/src/mycompany/mygoprog
ADD ./src/* /gopath/src/mycompany/mygoprog/
RUN CGO_ENABLED=0 GOOS=linux go build -a -tags rs -ldflags '-w' /gopath/src/mycompany/mygoprog/*.go
RUN cp mygoprog /mygoprog
CMD docker build -t foobar /gopath/src/mycompany/mygoprog

我的源代码目录中有我的Go程序(非常简单-可以编译/运行)和用于最终产品的Dockerfile:

FROM scratch
ADD /mygoprog mygoprog
ENTRYPOINT ["/mygoprog"]
EXPOSE 9100

这些文件的组织结构如下:

/myproject
   Dockerfile
   /src
      Dockerfile
      mygoprog.go

要启动构建过程,我进入顶级目录并运行:

docker build .

这个命令运行没有错误...但没有生成最终的镜像!输出如下所示:

bash-3.2$ docker build .
Sending build context to Docker daemon 6.656 kB
Sending build context to Docker daemon 
Step 0 : FROM google/golang
 ---> 3cc1d7ae0e9c
Step 1 : WORKDIR /gopath/src/mycompany/mygoprog
 ---> Using cache
 ---> 49b9686dcbed
Step 2 : RUN mkdir -p /gopath/src/mycompany/mygoprog
 ---> Using cache
 ---> 0d0139bb8cae
Step 3 : ADD ./src/* /gopath/src/mycompany/mygoprog/
 ---> 964ea5ca6afb
Removing intermediate container e57719a417d5
Step 4 : RUN CGO_ENABLED=0 GOOS=linux go build -a -tags rs -ldflags '-w' /gopath/src/mycompany/mygoprog/*.go
 ---> Running in 608ad65db52c
 ---> 6e91f06b7654
Removing intermediate container 608ad65db52c
Step 5 : RUN cp mygoprog /mygoprog
 ---> Running in 196af3db881b
 ---> 5e90e11ffc7d
Removing intermediate container 196af3db881b
Step 6 : CMD docker build -t foobar /gopath/src/mycompany/mygoprog
 ---> Running in 4794354abf2b
 ---> d91a908ee663
Removing intermediate container 4794354abf2b
Successfully built d91a908ee663

我错过了什么,以便获得一个包含我编译的程序的最终可运行的Docker容器?

英文:

I'm trying to build a very small Docker container for a Go program. To do that I'm hoping to use a Docker container to build the Go program then (within the container) build another Docker container to run the program.

Here's my build Dockerfile:

FROM google/golang
WORKDIR /gopath/src/mycompany/mygoprog

# Build the Contributors application
RUN mkdir -p /gopath/src/mycompany/mygoprog
ADD ./src/* /gopath/src/mycompany/mygoprog/
RUN CGO_ENABLED=0 GOOS=linux go build -a -tags rs -ldflags '-w' /gopath/src/mycompany/mygoprog/*.go
RUN cp mygoprog /mygoprog
CMD docker build -t foobar /gopath/src/mycompany/mygoprog

My source directory has my Go program (trivial--compiles/runs) and this Dockerfile for the final product:

FROM scratch
ADD /mygoprog mygoprog
ENTRYPOINT ["/mygoprog"]
EXPOSE 9100

These files are organized thusly:

/myproject
   Dockerfile
   /src
      Dockerfile
      mygoprog.go

To launch the build I go to the top directory and run:

docker build .

This runs without errors....and no final image! Output looks like this:

bash-3.2$ docker build .
Sending build context to Docker daemon 6.656 kB
Sending build context to Docker daemon 
Step 0 : FROM google/golang
 ---> 3cc1d7ae0e9c
Step 1 : WORKDIR /gopath/src/mycompany/mygoprog
 ---> Using cache
 ---> 49b9686dcbed
Step 2 : RUN mkdir -p /gopath/src/mycompany/mygoprog
 ---> Using cache
 ---> 0d0139bb8cae
Step 3 : ADD ./src/* /gopath/src/mycompany/mygoprog/
 ---> 964ea5ca6afb
Removing intermediate container e57719a417d5
Step 4 : RUN CGO_ENABLED=0 GOOS=linux go build -a -tags rs -ldflags '-w' /gopath/src/mycompany/mygoprog/*.go
 ---> Running in 608ad65db52c
 ---> 6e91f06b7654
Removing intermediate container 608ad65db52c
Step 5 : RUN cp mygoprog /mygoprog
 ---> Running in 196af3db881b
 ---> 5e90e11ffc7d
Removing intermediate container 196af3db881b
Step 6 : CMD docker build -t foobar /gopath/src/mycompany/mygoprog
 ---> Running in 4794354abf2b
 ---> d91a908ee663
Removing intermediate container 4794354abf2b
Successfully built d91a908ee663

What am I missing so I get a final, runnable Docker with my compiled program inside?

答案1

得分: 1

你已经生成了一个 Docker 镜像,但是由于你没有为其指定标签,所以只能通过哈希值(d91a908ee663)来访问。最好指定一个标签:docker build -t mygoprog . 如果你尝试在没有额外设置的情况下运行镜像,将会失败,因为容器内没有安装 Docker。在这里,最简单的解决方案是从容器中访问你的 Docker 守护进程:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker mygoprog

在你的发行版中,Docker 的位置可能不同,你可能还需要使用 --privileged 标志。

英文:

You've produced docker image, but as you haven't specified tag for it is accessible only by hash (d91a908ee663). It is better to specify tag: docker build -t mygoprog . And if you will try to run your image without additional setting it will fail because there is no docker inside of it. Easiest solution here to give access to your docker daemon from container:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker mygoprog

Docker location could be different in your distro, you also may need --privileged flag.

huangapple
  • 本文由 发表于 2015年5月15日 00:42:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/30242719.html
匿名

发表评论

匿名网友

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

确定