In this article, I'll demonstrate how to leverage Makefile in order to release lightweight Docker image for production.
Sample Application code
|
|
Of course, do not forget to vendor your dependencies: godep save
.
In order to create a release image, we first need to build the binary. We will have 2 Dockerfiles.
Main Dockerfile
The main Dockerfile is the “classic” one. For our example:
|
|
Note that the godep
install and the CGO disabled std rebuild are done before the maintainer, this allows to keep the cache for this part when the maintainer changes.
In a future article, I'll talk more in depth about static linking in Go (the -ldflags
and go install std
thingy)
Release Dockerfile
In order to release, we need a second Dockerfile. As Docker builds directories, we need to create a subdirectory release
.
The release Makefile is very straight forward and look like this:
|
|
Now, we need a Makefile to automate the process
Makefile
The Makefile allow for easy dependency scripting.
The goal is to push a “release” image. In order to do this, we need to have that image built.
In order to build this image, we need the binary, In order to get the binary, we need to build.
In order to build, we need the source. For convenience, we monitor .
instead of each individual go files.
The default rule is all
which triggers build
build
depends on .build
which is a file. If it exists then move on to the next dependency, otherwise, execute the rule. .build
depend on .
. This means that if anything changes in the current directoty, the cache gets invalidated and the rule will be executed.
In order to build, we call docker build
and create the .build
file.
The result is a full blown image roughly 600MB. release
will help with this.
The first step is to extract the binary and /etc/ssl
. The /etc/ssl
is mandatory only if you plan on using SSL (otherwise, Go will complain it does not find the certificates). Once extracted in a tarball, we build the release Dockerfile.
|
|
Directory tree
In the end, the directory tree should look like this:
|
|
Conclusion
As we saw, the release process is a dependency cascade, which make the Makefile very useful.
The advantages of using something like this is easily shown by docker images
:
Original image
|
|
Release image
|
|