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 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.