Spring Boot docker images are large! Building with jdk
as the base image, a Hello-World app reaches ~200MB easily.
The so called “Fat” JARs are large because they contain many JDK libraries which may not be even required by the program runnning inside it.
Use a jre
as the base image rather than a jdk
.
# add and extract the JAR to the /extracted dir inside the jre image
FROM eclipse-temurin:17.0.4.1_1-jre as builder
WORKDIR extracted
ADD target/*.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract
# take a fresh jre image and selectively copy extracted layers to /application dir inside it
FROM eclipse-temurin:17.0.4.1_1-jre
WORKDIR application
COPY --from=builder extracted/dependencies/ ./
COPY --from=builder extracted/spring-boot-loader/ ./
COPY --from=builder extracted/snapshot-dependencies/ ./
COPY --from=builder extracted/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Build the image with:
$ docker build -t foobar-service -f Dockerfile.layered .
Use Maven goal spring-boot:build-image
goal provided by Maven build plugin (added by default by Spring Initializr) takes care of layering as in above approach implicitly.
This approach doesn’t need a Dockerfile
to be present in the app directory, it ignores it if present. Since, best practices of creating Spring Boot app images are applied by Maven.
Specify image name and other properties in pom.xml
or with mvn command (shown below)
$ mvn spring-boot:build-image -Dspring-boot.build.image.imageName=abhishekarya1/myapp
Configure Google’s Jib plugin and it will build and push the image to Dockerhub or store it locally.
It doesn’t even need Docker to be installed on the machine!
It doesn’t even need a Dockerfile
to be present! It is highly opinionated and auto-applies best practices when building the image.
A 1.5MB Java Container App? Yes you can! by Shaun Smith - Devoxx - YouTube
Use Docker Compose to configure and run microservices together.