Docker multistage builds
So to start off, you will see below two images. They both run the application, but one has more bloat and unnecessary packages installed. The other only has the essential packages installed which greatly reduces the size of the image.
For some companies this may not be a big thing depending on their resources, but I think we can all agree if there's a way we can optimise something to make it better, we should aspire to improve.
For this example, I’m using the following repo which can be found here
So most people will tend to do something like this below:
FROM maven
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml -DskipTests clean package
ENTRYPOINT ["java","-jar","/usr/src/app/target/my-app-1.0-SNAPSHOT.jar"]
This will create the image with all the bloat as it has other packages installed such as all the Maven requirements instead of just the java jdk which is needed to run the application.
To get around this, what we can do is do a multistage Docker build.
Essentially what we’ll be doing is using a maven image as a builder, then using the openjdk alpine image for the files.
What we end up with is something like below:
FROM maven as builder
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml -DskipTests clean package
FROM openjdk:8u181-alpine3.8
COPY --from=builder /usr/src/app/target/my-app-1.0-SNAPSHOT.jar /usr/app/my-app-1.0-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/usr/app/my-app-1.0-SNAPSHOT.jar"]
As you can see. Both images do exactly the same. Except one used a multistage build process to produce a smaller image by then transferring the files and using just the jdk alpine image.