Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java Container Mastery: Options For Optimizing ...

Java Container Mastery: Options For Optimizing Images

In today's cloud-native landscape, containerizing Java applications has become a standard practice, but the path to optimal implementation remains unclear. This presentation dissects the various approaches to containerizing Java applications beyond the basic Dockerfile.
We'll examine the strengths and limitations of multiple container creation methods: traditional Dockerfiles, multi-stage Dockerfiles, Cloud-Native Buildpacks (buildpacks.io/paketo.io), Google's Jib, and custom solutions using jlink. Each approach will be evaluated through a comprehensive set of criteria:

Build efficiency and speed
Image size optimization
Enterprise standardization capabilities
Pipeline robustness
JVM memory configuration strategies
Security posture and vulnerability management

Through live demonstrations focusing primarily on modern Java frameworks (Spring Boot, Quarkus, and Micronaut), attendees will gain practical insights into selecting the right containerization strategy for their specific use cases. We'll also explore how GraalVM native image compilation introduces new considerations and opportunities for Java containerization, particularly for startup time and resource utilization.
While Java implementations serve as our primary examples, the principles discussed apply broadly across language ecosystems. Join this session to transform your containerization practices from merely functional to truly optimized for production environments.

Avatar for Matthias Haeussler

Matthias Haeussler

April 27, 2021

More Decks by Matthias Haeussler

Other Decks in Technology

Transcript

  1. 2

  2. Abstract In today's cloud-native landscape, containerizing Java applications has become

    a standard practice, but the path to optimal implementation remains unclear. This presentation dissects the various approaches to containerizing Java applications beyond the basic Dockerfile. We'll examine the strengths and limitations of multiple container creation methods: traditional Dockerfiles, multi-stage Dockerfiles, Cloud-Native Buildpacks (buildpacks.io/paketo.io), Google's Jib, and custom solutions using jlink. Each approach will be evaluated through a comprehensive set of criteria: Build efficiency and speed Image size optimization Enterprise standardization capabilities Pipeline robustness JVM memory configuration strategies Security posture and vulnerability management Through live demonstrations focusing primarily on modern Java frameworks (Spring Boot, Quarkus, and Micronaut), attendees will gain practical insights into selecting the right containerization strategy for their specific use cases. We'll also explore how GraalVM native image compilation introduces new considerations and opportunities for Java containerization, particularly for startup time and resource utilization. While Java implementations serve as our primary examples, the principles discussed apply broadly across language ecosystems. Join this session to transform your containerization practices from merely functional to truly optimized for production environments. 3
  3. @maeddes 16 FROM ubuntu:24.04 RUN apt update && apt install

    openjdk-21-jre-headless -y COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar CMD ["java","-jar","/opt/app.jar"] Dockerfile (simple)
  4. @maeddes Be careful - This will still “work”! 21 FROM

    adoptopenjdk:11-jre-hotspot COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar CMD ["java", "-jar", "/opt/app.jar"]
  5. @maeddes Multi-Stage Dockerfile 23 FROM maven:3-eclipse-temurin-25 AS build RUN mkdir

    -p /opt/app/src COPY src /opt/app/src COPY pom.xml /opt/app RUN mvn -f /opt/app/pom.xml package FROM eclipse-temurin:25-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]
  6. @maeddes Multi-Stage Dockerfile 24 FROM maven:3-eclipse-temurin-25 AS build RUN mkdir

    -p /opt/app/src COPY src /opt/app/src COPY pom.xml /opt/app RUN mvn -f /opt/app/pom.xml package FROM eclipse-temurin:25-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]
  7. @maeddes Multi-Stage Dockerfile 25 FROM maven:3-eclipse-temurin-25 AS build RUN mkdir

    -p /opt/app/src COPY src /opt/app/src COPY pom.xml /opt/app RUN mvn -f /opt/app/pom.xml package FROM eclipse-temurin:25-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]
  8. @maeddes Mount Cache 29 FROM maven:3-eclipse-temurin-25 AS build RUN mkdir

    -p /opt/app/src COPY src /opt/app/src COPY pom.xml /opt/app RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package FROM eclipse-temurin:25-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]
  9. @maeddes • Speed • Size • Structure • Simplicity •

    Security • Standardization Criteria 32
  10. @maeddes Layers 36 FROM eclipse-temurin:25-jre AS builder COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar

    app.jar RUN java -Djarmode=tools -jar app.jar extract --layers --destination extracted FROM eclipse-temurin:25-jre COPY --from=builder extracted/dependencies/ ./ COPY --from=builder extracted/spring-boot-loader/ ./ COPY --from=builder extracted/snapshot-dependencies/ ./ COPY --from=builder extracted/application/ ./ ENTRYPOINT ["java","-jar", "application.jar"]
  11. @maeddes Entire file 37 FROM maven:3-eclipse-temurin-25 AS builder WORKDIR /opt/app

    COPY src ./src COPY pom.xml . RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package -DskipTests FROM eclipse-temurin:25-jre AS extractor WORKDIR /opt/app COPY --from=builder /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted FROM eclipse-temurin:25-jre WORKDIR /opt/app COPY --from=extractor /opt/app/extracted/dependencies/ ./ COPY --from=extractor /opt/app/extracted/spring-boot-loader/ ./ COPY --from=extractor /opt/app/extracted/snapshot-dependencies/ ./ COPY --from=extractor /opt/app/extracted/application/ ./ ENTRYPOINT ["java", "-jar", "application.jar"]
  12. 39

  13. @maeddes jlink and jdeps 40 FROM maven:3-eclipse-temurin-25 AS build RUN

    --mount=type=cache,target=/root/.m2 mvn package RUN jdeps --ignore-missing-deps -q \ --recursive \ --multi-release 21 \ --print-module-deps \ --class-path 'BOOT-INF/lib/*' \ target/simplecode-0.0.1-SNAPSHOT.jar > deps.info RUN jlink \ --add-modules $(cat deps.info) \ --strip-debug \ --compress 2 \ --no-header-files \ --no-man-pages \ --output /myjre FROM debian:bookworm-slim COPY --from=build /myjre $JAVA_HOME COPY --from=build /usr/src/project/target/simplecode-0.0.1-SNAPSHOT.jar /project/
  14. 41 FROM maven:3-eclipse-temurin-25 AS build RUN mkdir /opt/app COPY src

    /opt/app/src COPY pom.xml /opt/app WORKDIR /opt/app RUN --mount=type=cache,target=/root/.m2 mvn package -DskipTests RUN jar xf target/simplecode-0.0.1-SNAPSHOT.jar RUN jdeps --ignore-missing-deps -q \ --recursive \ --multi-release 21 \ --print-module-deps \ --class-path 'BOOT-INF/lib/*' \ target/simplecode-0.0.1-SNAPSHOT.jar > deps.info RUN jlink \ --add-modules $(cat deps.info) \ --strip-debug \ --compress 2 \ --no-header-files \ --no-man-pages \ --output /myjre FROM eclipse-temurin:25-jre AS extractor RUN mkdir /opt/app WORKDIR /opt/app COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted FROM ubuntu:jammy ENV JAVA_HOME /opt/java/jdk25 ENV PATH $JAVA_HOME/bin:$PATH COPY --from=build /myjre $JAVA_HOME RUN mkdir /opt/app WORKDIR /opt/app COPY --from=extractor /opt/app/extracted/dependencies/ ./ COPY --from=extractor /opt/app/extracted/spring-boot-loader/ ./ COPY --from=extractor /opt/app/extracted/snapshot-dependencies/ ./ COPY --from=extractor /opt/app/extracted/application/ ./ ENTRYPOINT ["java", "-jar", "application.jar"]
  15. 50

  16. @maeddes Summary 68 • Be aware of options and possibilities

    • Be aware of the possibilities of your options • Keep your base images and layers as consistent as possible throughout your landscape • Avoid “wild growth” through dockerfiles • Automate and standardize as much as possible • There is no universally best option. There is a best fit depending on whether you optimize for control, developer speed, or platform standardization.
  17. @maeddes 69 Dockerfile (simple) Dockerfile (multistage) Dockerfile (jlink/jdeps) Jib Buildpacks/

    Paketo Speed 🤩 Size 🤩 Structure 🙂 🙂 🤩 🤩 Standardization 🙂 🙂 🙂 🤩 Simplicity 🙂 🤩 🙂 Security 🙂 🤩 🙂
  18. @maeddes Supply Chain Security, SBOMs, Attestations 74 • Container images

    are no longer just runtime artifacts — they are also verifiable delivery artifacts • SBOMs answer: What is inside the image? • Provenance / attestations answer: Where, how, and with what was it built? • Modern tooling such as BuildKit / Docker Build / Buildpacks supports SBOM and provenance attestations
  19. @maeddes Secure Base Images / Hardened Images 75 • Secure

    images aim for minimal footprint, reduced CVE exposure, and strong provenance • Docker Hardened Images, Bellsoft & Chainguard/Wolfi images are positioned as minimal, production-ready, and security-focused • They also provide verifiable SBOMs, provenance information, and signed attestations • Additional features such as non-root defaults and compliance-oriented variants support regulated environments • New baseline question for production images: Is the base image only small — or also trusted, patchable, and verifiable?
  20. @maeddes Docker Hardened Images 76 • Direct replacement of traditional

    images • Free since 2025 • Various levels of hardening / support • About 1000 images available • Categories ◦ Languages & Frameworks ◦ Databases & Messaging ◦ Service components of all kind
  21. Sources @maeddes ▪ https://www.excalidraw.com ▪ https://docs.docker.com/engine/release-notes/prior-releases/ ▪ https://blog.codecentric.de/en/2020/11/buildpacks-spring-boot/ ▪ https://paketo.io/

    ▪ https://buildpacks.io/features/ ▪ https://github.com/GoogleContainerTools/jib ▪ https://www.baeldung.com/docker-layers-spring-boot ▪ https://spring.io/blog/2020/01/27/creating-docker-images-with- spring-boot-2-3-0-m1 ▪ https://github.com/openshift/source-to-image 80