Why multi-stage build?
- One of the most difficult things about building images is keeping the size of an image as small as possible.
- The multi-stage build is a new feature and it requires Docker 17.05 or higher on the daemon and client.
Before multi-stage build!
- Before multi-stage build, It was common to have one Dockerfile to use for development (which has everything needed to build your application), and a smaller one to use for production, which only contained your application and exactly what was needed to run it.
How Multi-stage Build Works
- With multi-stage builds, you use multiple
FROMstatements in your Dockerfile.
FROMinstruction can use a different base, and each of them begins a new stage of the build.
- We can selectively copy artifacts from one stage to another, leaving behind everything we don’t want in the final image.
A Simple Multi-Stage Dockerfile
#Build image FROM gradle:4.5-jdk-alpine as BUILD_IMAGE RUN mkdir /home/src COPY ./app/ /home/app/ WORKDIR /home/app RUN gradle build #Final run image FROM openjdk:8-jre-alpine RUN mkdir /home/app WORKDIR /home/app COPY --from=BUILD_IMAGE /home/app/build/libs/myapp.jar . CMD ["java","-jar","myapp.jar"]
In multi-stage build, we pick the tasks of building and running our applications into different stages. Here, we start with a large image that includes all of the necessary dependencies needed to compile the binary executable of our application. This can be termed as the builder stage.
We then took a lightweight image for our run stage which includes only what is needed to run a binary executable. i.e just having jre in our final stage is sufficient to run our application. This can be termed as the production stage.
As we’ve seen multi-stage Dockerfile allows us to build smaller images, and separate build into stages. For example, in the first stage you can create a complete build environment and in the second stage, create a minimal runtime environment using a single Dockerfile.