最近开始做毕设了,着手的地方是构建docker image的环节,于是尝试过各种build docker image的奇技淫巧,其中有一种是比较实用的技巧,其思想很简单,就是把构建分成两步,第一步是先构建出需要的二进制,第二步是把二进制打包进image中。
这样做的好处是,可以尽可能地简化最终构建出来的image的逻辑与规模。举个简单的例子啊~dyweb/Ayi是一个golang写的cli工具,如果要构建一个关于它的镜像,可以先:
$ docker run --rm -v `pwd`:/go/src/github.com/dyweb/Ayi\
-e GOPATH=/go:/go/src/github.com/dyweb/Ayi/Godeps/_workspace\
golang:1.5.3 sh -c \
"cd /go/src/github.com/dyweb/Ayi && go build ."
这样构建出来的Linux下的二进制就会在host的当前目录中看到,之后就可以直接把这个二进制打包进Image中。可以看到,我们是利用golang的image来做build的,因为这个项目技术栈比较浅,不需要其他依赖的支持,只需要有golang的二进制就可以build。而如果一个项目,有很多的依赖,这个时候应该用什么样的方式来进行构建呢~
rancher/dapper是一个focus在这个问题上的工具。
Dapper is a tool to wrap any existing build tool in an consistent environment. This allows people to build your software from source or modify it without worry about setting up a build environment. The approach is very simple and taken from a common pattern that has adopted by many open source projects. Create a file called Dockerfile.dapper in the root of your repository. Dapper will build that Dockerfile and then execute a container based off of the resulting image. Dapper will also copy in source files and copy out resulting artifacts or will use bind mounting if you choose.
rancher自家的rancher/os就是用这样的方式进行构建的。这样的构建方式要求目录下要有两个Dockerfile,其中一个用来输出构建的artifacts,另外一个就是真正被用来构建镜像的Dockerfile,会使用已经得到的artifacts来进行真正的构建。
如果想试一试这样的构建方式,可以直接在rancher/dapper执行:
$ go build .
$ ./dapper
试试看,看看会输出什么内容,如果你在OS X下而且是使用bind的模式,就会发现./dapper会在执行完一次后就不能用了,因为dapper已经被resulting artifacts覆盖了,是linux format的binary了。