Nico
Nico
Creator of this small website
Sep 5, 2017 2 min read

Docker Multistage And Golang static binaries

thumbnail for this post

Recently I have been working on creating a docker image containing dnsControl. I wanted to minimize the size of the image, and use the feature of go producing a single binary. Nothing fancy here, you can find lots of links about it.

A quite recent docker feature at the time of this writing is the multi stage build. Where I was previously making different step with either a shell script or jenkins scripts as a glue, it is now possible to do everything in a single Dockerfile (and docker build call)

I ended up with the following version :

# multi stage build. needs docker >= 17.05
FROM golang:latest as builder
MAINTAINER Nicolas Szalay <XXXX>

RUN go get github.com/StackExchange/dnscontrol
WORKDIR /go/src/github.com/StackExchange/dnscontrol
RUN CGO_ENABLED=0 GOOS=linux go build -v -o dnsControl .

# final stage
FROM scratch
MAINTAINER Nicolas Szalay <XXXX>

ADD files/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /go/src/github.com/StackExchange/dnscontrol/dnsControl /

CMD ["/dnsControl"]

The ca-certificates.crt file is here to address a common gotcha of using the scratch image and golang binaries.

While I was quite happy with it, but still annoyed with a static file hanging in my repo, my colleague suggested during review to use the ca-certificates.crt from the builder, since it was available. Resulting in having the ADD line replaced by :

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

And yeah, a final image usable by all the team that is under 20MB in size.