In my previous post I used Docker multi stage technique to build a Docker container image which only has the golang executable in a tiny Alpine Linux base image. I’ll go further to use the
scratch base image which has basically nothing.
Here’s the Dockerfile I tested on my own project, I’ve also added comments to help understand important lines:
FROM golang:1.13.1 AS builder # ENVs to ensure golang will need no external libraries ENV CGO_ENABLED=0 GOOS=linux WORKDIR /app COPY . . # build switches to ensure golang will need no external libraries RUN go build -a -installsuffix cgo -o myapp main.go && \ # create non-privileged user and group to run the app addgroup --system --gid 2000 golang && \ adduser --system --gid 2000 --uid 2000 golang FROM scratch # some sample ENVs for the app ENV API_KEY=xxx \ API_EMAIL=xxx WORKDIR /app # copy the golang executable over COPY --from=builder /app/myapp . # scratch has no <code>adduser</code> command so just copy the files from builder COPY --from=builder /etc/passwd /etc/passwd COPY --from=builder /etc/group /etc/group # use the CA cert from builder to enable HTTPS access COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ USER golang # run the executable directly ENTRYPOINT ["/app/myapp"]
The result image is only 7.7MB, only 1MB larger than the golang app itself. 🙂