Multi-stage docker images

When working with docker images, it would be a good idea to keep the final image (especially for production) as small as possible. Usually, when building apps, there are a lot of extra stuff included that are really not necessary for the final image. This can be most obvious with Spring Boot applications, where build process downloads a lot of dependencies and builds a ‘fat’ jar file, which includes all dependencies.

Instead of having everything included into one docker image, we can use a multi-stage docker build process and copy only what we need into a final image.

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. To show how this works, let’s adapt the Dockerfile from the previous section to use multi-stage builds.

Example:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  

Docs: https://docs.docker.com/develop/develop-images/multistage-build/

Example with java: https://aboullaite.me/multi-stage-docker-java/