Building compact golang docker images

by Gregor Uhlenheuer on April 10, 2019

Building compact or minimal docker images is nothing new at all. However with multi-stage docker builds there is (now) a very easy way to create such images without too much complications. These kind of multi-stage builds do exist in docker for quite some time already but I didn’t know until just recently.

Moreover golang lends itself very nicely to compile to statically linked executables and is therefore a perfect candidate to be put into stripped down containers.

Multi-stage builds

Using multi-stage builds you can describe docker files that are constructed by multiple different (base-) images that are chained one after another while being able to share artifacts - and this inside just one Dockerfile.

Usually you had to imitate such a behavior by creating so called “builder” docker images that replicated an isolated build environment, just to inject the resulting build artifacts into the actual runtime docker image at a later point.

Builder stage

This time that we want to package a golang application into a docker container. That’s why we choose the “official” golang image as our starting point for the first “builder” stage:

Runtime stage

Now that we have described the building phase of the docker image we can assemble the image components for the actual runtime of the application. We actually have multiple possibilities to go with:

We are going to use the alpine base image in here as we do need some additional runtime dependencies (ca-certificates for SSL to be specific):

Building

You can build the final docker image with a single call to docker build just as you are used to:

$ docker build -t kongo2002/go-test -f Dockerfile .

In my example this results in a pretty tiny docker image (YMMV):

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
kongo2002/go-test   latest              14f8984cd4a1        About an hour ago   11.5MB
References

This post is tagged with programming, docker, golang, linux, alpine and container