Docker Multistage And Golang static binaries
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
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"]
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.