Slide 1

Slide 1 text

Dockerfiles, Buildpacks, Jib and more ... what's the best way to run your Java code in Containers? Matthias Haeussler, Chief Technologist @maeddes

Slide 2

Slide 2 text

2

Slide 3

Slide 3 text

@maeddes | 3 What we really do

Slide 4

Slide 4 text

@maeddes | 4 What we really do

Slide 5

Slide 5 text

@maeddes | 5 What we really do

Slide 6

Slide 6 text

@maeddes | 6 What we really do

Slide 7

Slide 7 text

@maeddes | What I do/ What we do 7

Slide 8

Slide 8 text

@maeddes | Situation 8

Slide 9

Slide 9 text

@maeddes | Options 9

Slide 10

Slide 10 text

@maeddes | Options 10

Slide 11

Slide 11 text

@maeddes | Situation 11

Slide 12

Slide 12 text

@maeddes | Lab Repo 12

Slide 13

Slide 13 text

@maeddes | „What is the best Java base container image?“ 13

Slide 14

Slide 14 text

@maeddes | 14

Slide 15

Slide 15 text

@maeddes | 15

Slide 16

Slide 16 text

@maeddes | „What is the best Java base container image?“ 16

Slide 17

Slide 17 text

@maeddes | Container Images as Templates 17

Slide 18

Slide 18 text

@maeddes | Container, Images & Layers 18

Slide 19

Slide 19 text

@maeddes | Docker History 19 [1]

Slide 20

Slide 20 text

@maeddes | 20 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)

Slide 21

Slide 21 text

@maeddes | Java today 21

Slide 22

Slide 22 text

@maeddes | Alternative Dockerfile 22 FROM eclipse-temurin:21-jre COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar CMD ["java", "-jar", "/opt/app.jar"]

Slide 23

Slide 23 text

@maeddes | Alternative Dockerfile 23 FROM ibm-semeru-runtimes:open-21-jre COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar CMD ["java", "-jar", "/opt/app.jar"]

Slide 24

Slide 24 text

@maeddes | JVM Landscape Talk - Gerrit Grunwald 24 https://www.youtube.com/watch?v=9_9L3pqGFcQ

Slide 25

Slide 25 text

@maeddes | Beware! 25

Slide 26

Slide 26 text

@maeddes | Be careful - This will still “work”! 26 FROM adoptopenjdk:11-jre-hotspot COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar CMD ["java", "-jar", "/opt/app.jar"]

Slide 27

Slide 27 text

@maeddes | Multi-Stage 27 [1]

Slide 28

Slide 28 text

@maeddes | Multi-Stage Dockerfile 28 FROM maven:3-eclipse-temurin-21 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:21-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]

Slide 29

Slide 29 text

@maeddes | Multi-Stage Dockerfile 29 FROM maven:3-eclipse-temurin-21 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:21-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]

Slide 30

Slide 30 text

@maeddes | Multi-Stage Dockerfile 30 FROM maven:3-eclipse-temurin-21 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:21-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]

Slide 31

Slide 31 text

@maeddes | Buildkit 31 [1]

Slide 32

Slide 32 text

@maeddes | 32

Slide 33

Slide 33 text

@maeddes | 33

Slide 34

Slide 34 text

@maeddes | Mount Cache 34 FROM maven:3-eclipse-temurin-21 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:21-jre COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar ENTRYPOINT ["java","-jar","/opt/app.jar"]

Slide 35

Slide 35 text

@maeddes | „What makes a (Java) container image good?“ 35

Slide 36

Slide 36 text

@maeddes | • Speed • Size • Structure • Standardization • Simplicity • Security Criteria 36

Slide 37

Slide 37 text

@maeddes | • Speed • Size • Structure • Standardization • Simplicity • Security • JVM configuration Criteria 37

Slide 38

Slide 38 text

@maeddes | The reality … 38

Slide 39

Slide 39 text

@maeddes | Considerations for structure and size 39

Slide 40

Slide 40 text

@maeddes | Considerations for Java 40

Slide 41

Slide 41 text

@maeddes | Layered Jar 41 FROM eclipse-temurin:21-jre AS builder COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar RUN java -Djarmode=layertools -jar application.jar extract FROM eclipse-temurin:21-jre COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java","org.springframework.boot.loader.JarLauncher"]

Slide 42

Slide 42 text

@maeddes | Entire file 42 FROM maven:3-eclipse-temurin-21 AS maven 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:21-jre AS builder WORKDIR application COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar RUN java -Djarmode=layertools -jar application.jar extract FROM eclipse-temurin:21-jre WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","org.springframework.boot.loader.JarLauncher"]

Slide 43

Slide 43 text

@maeddes | Dockerfile and jlink (and jdeps) 43 https://snyk.io/blog/jlink-create-docker-images-spring-boot-java/

Slide 44

Slide 44 text

44

Slide 45

Slide 45 text

@maeddes | jlink and jdeps 45 FROM maven:3-eclipse-temurin-21 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/

Slide 46

Slide 46 text

46 FROM maven:3-eclipse-temurin-21 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:21-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=layertools -jar application.jar extract FROM ubuntu:jammy ENV JAVA_HOME /opt/java/jdk21 ENV PATH $JAVA_HOME/bin:$PATH COPY --from=build /myjre $JAVA_HOME RUN mkdir /opt/app WORKDIR /opt/app COPY --from=extractor /opt/app/dependencies/ ./ COPY --from=extractor /opt/app/spring-boot-loader/ ./ COPY --from=extractor /opt/app/snapshot-dependencies/ ./ COPY --from=extractor /opt/app/application/ ./ ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","org.springframework.boot.loader.JarLauncher"]

Slide 47

Slide 47 text

@maeddes | 47 Dockerfile Learnings

Slide 48

Slide 48 text

48 & more …?

Slide 49

Slide 49 text

@maeddes | 49 [2]

Slide 50

Slide 50 text

@maeddes | 50 [2]

Slide 51

Slide 51 text

51

Slide 52

Slide 52 text

@maeddes | Jib 52

Slide 53

Slide 53 text

@maeddes | Jib 53

Slide 54

Slide 54 text

@maeddes | Jib 54

Slide 55

Slide 55 text

@maeddes | Considerations - Recap 55

Slide 56

Slide 56 text

@maeddes | Continued strategy 56

Slide 57

Slide 57 text

@maeddes | Jib 57

Slide 58

Slide 58 text

58 Cloud-Native Buildpacks buildpacks.io

Slide 59

Slide 59 text

@maeddes | Buildpacks idea 59

Slide 60

Slide 60 text

@maeddes | History 60

Slide 61

Slide 61 text

@maeddes | Flow 61

Slide 62

Slide 62 text

@maeddes | Rebase 62

Slide 63

Slide 63 text

63 paketo.io

Slide 64

Slide 64 text

@maeddes | Multi Runtime/Language Support 64 [3]

Slide 65

Slide 65 text

@maeddes | Rebase 65

Slide 66

Slide 66 text

@maeddes | 66 Flow

Slide 67

Slide 67 text

@maeddes | Java settings 67

Slide 68

Slide 68 text

@maeddes | 68

Slide 69

Slide 69 text

@maeddes | Summary 69 • 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 • Give jib and buildpacks a try

Slide 70

Slide 70 text

@maeddes | 70 Dockerfile (simple) Dockerfile (multistage) Dockerfile (jlink/jdeps) Jib Buildpacks/ Paketo Speed 🤩 Size 🤩 Structure 🙂 🙂 🤩 🤩 Standardization 🙂 🙂 🙂 🤩 Simplicity 🙂 🤩 🙂 Security 🙂 🤩 🙂

Slide 71

Slide 71 text

@maeddes | Lab Repo 71

Slide 72

Slide 72 text

Novatec Consulting GmbH Bertha-Benz-Platz 1 D-70771 Leinfelden-Echterdingen T. +49 711 22040-700 info@novatec-gmbh.de www.novatec-gmbh.de 72 Chief Technologist Matthias Haeussler Mobil: +49 175 222 5949 E-Mail: matthias.haeussler@novatec-gmbh.de Twitter: @maeddes

Slide 73

Slide 73 text

Sources @maeddes | ▪ https://www.excalidraw.com ▪ [1] https://docs.docker.com/engine/release-notes/prior-releases/ ▪ [2] https://blog.codecentric.de/en/2020/11/buildpacks-spring-boot/ ▪ [3] 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 73