From 8e301fddab150d2bbc1771da40987b2b9173c38b Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Tue, 20 Jan 2026 14:00:07 +0200 Subject: [PATCH 1/3] Resolve conflicts --- .../Dockerfile.distroless-base.mostly | 2 +- .../Dockerfile.distroless-java-base-jar | 2 +- .../Dockerfile.distroless-java-base.dynamic | 2 +- ...ile.distroless-java-base.dynamic-optimized | 2 +- ...file.distroless-java-base.dynamic-skipflow | 11 +++ .../Dockerfile.distroless-java-base.jlink | 2 +- .../Dockerfile.eclipse-temurin-jar | 2 +- native-image/spring-boot-webserver/README.md | 96 ++++++++++++++++--- .../build-jar-eclipse-temurin.sh | 4 +- .../build-jar-java-base.sh | 2 +- native-image/spring-boot-webserver/pom.xml | 4 +- 11 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-base.mostly b/native-image/spring-boot-webserver/Dockerfile.distroless-base.mostly index c59ffb30..a8624f17 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-base.mostly +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-base.mostly @@ -5,7 +5,7 @@ WORKDIR /webserver RUN ./mvnw -Dmaven.test.skip=true -Pnative,mostly-static native:compile # Distroless Base - provides glibc -FROM gcr.io/distroless/base-debian12 +FROM gcr.io/distroless/base-debian13 COPY --from=nativebuild /webserver/target/webserver.mostly-static / EXPOSE 8000 ENTRYPOINT ["/webserver.mostly-static", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar index 9e07b01e..05ecb777 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar @@ -5,7 +5,7 @@ RUN ./mvnw clean package ##### TODO: Upgrade to Distroless Java 25 (Debian) # Distoless Java 21 (Debian) -FROM gcr.io/distroless/java21-debian12 +FROM gcr.io/distroless/java25-debian13 COPY --from=build /webserver/target/webserver-0.0.1-SNAPSHOT.jar webserver-0.0.1-SNAPSHOT.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "webserver-0.0.1-SNAPSHOT.jar"] \ No newline at end of file diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic index 9eb0db17..52e17906 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic @@ -5,7 +5,7 @@ WORKDIR /webserver RUN ./mvnw -Dmaven.test.skip=true -Pnative native:compile # Distroless Java Base - provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=nativebuild /webserver/target/webserver.dynamic / EXPOSE 8000 ENTRYPOINT ["/webserver.dynamic", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-optimized b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-optimized index 08bb21b9..013e40d1 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-optimized +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-optimized @@ -5,7 +5,7 @@ WORKDIR /webserver RUN ./mvnw -Dmaven.test.skip=true -Pnative,dynamic-size-optimized native:compile # Distroless Java Base-provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=nativebuild /webserver/target/webserver.dynamic-optimized / EXPOSE 8000 ENTRYPOINT ["/webserver.dynamic-optimized", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow new file mode 100644 index 00000000..3107f360 --- /dev/null +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow @@ -0,0 +1,11 @@ +FROM container-registry.oracle.com/graalvm/native-image:24 AS nativebuild +COPY . /webserver +WORKDIR /webserver +# Build a dynamically linked native image with optimization for size +RUN ./mvnw -Dmaven.test.skip=true -Pnative,dynamic-skipflow-optimized native:compile + +# Distroless Java Base-provides glibc and other libraries needed by the JDK +FROM gcr.io/distroless/java-base-debian13 +COPY --from=nativebuild /webserver/target/webserver.dynamic-skipflow / +EXPOSE 8000 +ENTRYPOINT ["/webserver.dynamic-skipflow", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.jlink b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.jlink index a091ee23..4727c1e2 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.jlink +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.jlink @@ -16,7 +16,7 @@ RUN jlink \ --output jlink-jre # Distroless Java Base-provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=build /webserver/target/webserver-0.0.1-SNAPSHOT.jar webserver-0.0.1-SNAPSHOT.jar COPY --from=build /webserver/jlink-jre jlink-jre EXPOSE 8080 diff --git a/native-image/spring-boot-webserver/Dockerfile.eclipse-temurin-jar b/native-image/spring-boot-webserver/Dockerfile.eclipse-temurin-jar index 77543577..4cfdfee3 100644 --- a/native-image/spring-boot-webserver/Dockerfile.eclipse-temurin-jar +++ b/native-image/spring-boot-webserver/Dockerfile.eclipse-temurin-jar @@ -3,7 +3,7 @@ COPY . /webserver WORKDIR /webserver RUN ./mvnw clean package -# Eclipse Temurin Java 25 +# Distoless Java 25 (Debian) FROM eclipse-temurin:25 COPY --from=build /webserver/target/webserver-0.0.1-SNAPSHOT.jar webserver-0.0.1-SNAPSHOT.jar EXPOSE 8080 diff --git a/native-image/spring-boot-webserver/README.md b/native-image/spring-boot-webserver/README.md index 72dddb28..d9f966a1 100644 --- a/native-image/spring-boot-webserver/README.md +++ b/native-image/spring-boot-webserver/README.md @@ -28,7 +28,7 @@ In this workshop you will: * x86 Linux * `musl` toolchain * Container runtime such as [Docker](https://www.docker.com/gettingstarted/), or [Rancher Desktop](https://docs.rancherdesktop.io/getting-started/installation/) installed and running. -* [GraalVM 25](https://www.graalvm.org/downloads/). We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) +* [Oracle GraalVM 25](https://www.graalvm.org/downloads/). We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) ```bash sdk install java 25-graal ``` @@ -67,7 +67,7 @@ It requires a container image with a full JDK and runtime libraries. ### Explanation -The Dockerfile provided for this step pulls [container-registry.oracle.com/graalvm/jdk:25](https://docs.oracle.com/en/graalvm/jdk/25/docs/getting-started/container-images/) for the builder, and then `gcr.io/distroless/java21-debian12` for the runtime. +The Dockerfile provided for this step pulls [container-registry.oracle.com/graalvm/jdk:25](https://docs.oracle.com/en/graalvm/jdk/25/docs/getting-started/container-images/) for the builder, and then `gcr.io/distroless/java25-debian13` for the runtime. The entrypoint for this image is equivalent to `java -jar`, so only a path to a JAR file is specified in `CMD`. ### Action @@ -285,7 +285,7 @@ In this step, you will build a fully dynamically linked native image **with the GraalVM Native Image provides the option `-Os` which optimizes the resulting native image for file size. `-Os` enables `-O2` optimizations except those that can increase code or executable size significantly. -Learn more in [the Native Image documentation](https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/#optimization-levels). +Learn more in [the Native Image documentation](https://www.graalvm.org/jdk25/reference-manual/native-image/optimizations-and-performance/#optimization-levels). For that, a separate Maven profile is provided to differentiate this run from the default build, and giving a different name for the output file: ```xml @@ -348,7 +348,78 @@ The Dockerfile for this step, _Dockerfile.distroless-java-base.dynamic-optimized The size of the native executable decreased from **103MB** to **69MB** by applying the file size optimization! -## **STEP 6**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container +## **STEP 6**: (Optional) Build a Size-Optimized Native Image with SkipFlow and Run Inside a Container + +In this step, you will build another fully dynamically linked native image but with the **SkipFlow** and **file size** optimizations on. Then you run it inside a container. + +### Explanation + +As of Oracle GraalVM 25, more performance improvements are enabled by default. One of which is [SkipFlow](https://www.graalvm.org/release-notes/JDK_25/#native-image)-an extension to the Native Image static analysis that tracks primitive values and evaluates branching conditions dynamically during the process. + +Note: The feature is enabled by default. With the previous releases, it could be controlled using these host options: `-H:+TrackPrimitiveValues` and `-H:+UsePredicates`. + +For that, a separate Maven profile is provided, giving a different name for the output file: +```xml + + dynamic-skipflow-optimized + + + + org.graalvm.buildtools + native-maven-plugin + + webserver.dynamic-skipflow + + -Os + -H:+UnlockExperimentalVMOptions + -H:+TrackPrimitiveValues + -H:+UsePredicates + + + + + + +``` + +The Dockerfile for this step, _Dockerfile.distroless-java-base.dynamic-skipflow_, is pretty much the same as before: running a native image build inside the builder container, and then copying it over to a distroless base container with just enough to run the application. No Java Runtime Environment (JRE) is required. + +### Action + +1. Run the script to build a size-optimized native executable and package it into a container: + ```bash + ./build-dynamic-image-skipflow.sh + ``` + +2. Once the build completes, a container image _distroless-java-base.dynamic-optimized_ should be available. Run it, mapping the ports: + ```bash + docker run --rm -p8080:8080 webserver:distroless-java-base.dynamic-skipflow + ``` + + The application is running from the native image inside a container. + The startup time has not changed. + +3. Open a browser and navigate to [localhost:8080/](http://localhost:8080/). You see the GraalVM documentation pages served. + +4. Return to the terminal and stop the running container by clicking CTRL+C. + +5. Check the size of this container image: + ```bash + docker images + ``` + The expected output is: + ```bash + REPOSITORY TAG IMAGE ID CREATED SIZE + webserver distroless-java-base.dynamic-skipflow 7c748db34ef4 2 hours ago 103MB + webserver distroless-java-base.dynamic-optimized 5e16a58b1649 2 hours ago 105MB + webserver distroless-java-base.dynamic d7c449b9373d 2 hours ago 141MB + webserver distroless-java-base.jlink 191efb04958d 2 hours ago 178MB + webserver distroless-java-base.jar 846971900174 2 hours ago 225MB + webserver.buildpacks latest 615deed5b89c 45 years ago 142MB + ``` + The gain is tiny: the container size reduced only by 2MB, from 105MB to **103MB**, but depending on the application, **SkipFlow can provide up to a 4% reduction in binary size without any additional impact on build time**. + +## **STEP 7**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container In this step, you will build a **mostly static** native image, with the file size optimization on, and then package it into a container image that provides `glibc`, and run. @@ -414,9 +485,9 @@ A separate Maven profile exists for this step: ``` The size of the new _distroless-base.mostly-static_ container is **92.7MB**. - The reduction in size is related to the fact that a smaller base image was pulled: **gcr.io/distroless/base-debian12**. + The reduction in size is related to the fact that a smaller base image was pulled: **gcr.io/distroless/base-debian13**. [Distroless images](https://github.com/GoogleContainerTools/distroless) are very small, and the one used is only **48.3 MB**. - That's about 50% of the size of **java-base-debian12**(124 MB) used before, and 3 times less than **java21-debian12** (192 MB) containing a full JDK. + That's about 50% of the size of **java-base-debian13**(124 MB) used before, and 3 times less than **java25-debian13** (192 MB) containing a full JDK. The size of the mostly static native image has not changed, and is **69MB**. @@ -577,13 +648,14 @@ Sorted by size, it is clear that the fully static native image, compressed with | Container | Size of a build artefact
(JAR, Jlink runtime, native executable) | Base image | Container | |----------------------------------------|-----------------------------------------------------------------------|------------|-----------| -| eclipse-temurin-jar | webserver-0.0.1-SNAPSHOT.jar **32M** | eclipse-temurin:25 201MB | 481MB | -| distroless-java-base.jar | webserver-0.0.1-SNAPSHOT.jar **32M** | java21-debian12 192MB | 225MB | -| distroless-java-base.jlink | jlink-jre custom runtime **68MB** | java-base-debian12 128MB | 178MB | -| distroless-java-base.dynamic | webserver.dynamic **103MB** | java-base-debian12 128MB | 141MB | +| eclispe-temurin-jar | webserver-0.0.1-SNAPSHOT.jar **32M** | eclipse-temurin:25 201MB | 481MB | +| distroless-java-base.jar | webserver-0.0.1-SNAPSHOT.jar **32M** | java25-debian13 192MB | 225MB | +| distroless-java-base.jlink | jlink-jre custom runtime **68MB** | java-base-debian13 128MB | 178MB | +| distroless-java-base.dynamic | webserver.dynamic **103MB** | java-base-debian13 128MB | 141MB | | webserver.buildpacks:latest | | | 142MB | -| distroless-java-base.dynamic-optimized | webserver.dynamic-optimized **69MB** | java-base-debian12 128MB | 105MB | -| distroless-base.mostly-static | webserver.mostly-static **69MB** | base-debian12 48.3MB | 92.7MB | +| distroless-java-base.dynamic-optimized | webserver.dynamic-optimized **69MB** | java-base-debian13 128MB | 105MB | +| distroless-java-base.dynamic-skipflow | webserver.dynamic-skipflow **67MB** | java-base-debian13 128MB | 103MB | +| distroless-base.mostly-static | webserver.mostly-static **69MB** | base-debian13 48.3MB | 92.7MB | | scratch.static-alpine | webserver.static **69MB** | alpine:3 5MB | 80.5MB | | scratch.static | webserver.static **69MB** | scratch 2MB | 72.2MB | | scratch.static-upx | webserver.scratch.static-upx **19MB** | scratch 2MB | 19.1MB | diff --git a/native-image/spring-boot-webserver/build-jar-eclipse-temurin.sh b/native-image/spring-boot-webserver/build-jar-eclipse-temurin.sh index 82dee3ce..01385fb1 100755 --- a/native-image/spring-boot-webserver/build-jar-eclipse-temurin.sh +++ b/native-image/spring-boot-webserver/build-jar-eclipse-temurin.sh @@ -1,4 +1,4 @@ #!/bin/sh -# Eclipse Temurin Java 25 -docker build --no-cache . -f Dockerfile.eclipse-temurin-jar -t webserver:eclipse-temurin-jar \ No newline at end of file +# Eclipse-temurin:25 +docker build --no-cache . -f Dockerfile.eclispe-temurin-jar -t webserver:eclispe-temurin-jar diff --git a/native-image/spring-boot-webserver/build-jar-java-base.sh b/native-image/spring-boot-webserver/build-jar-java-base.sh index d190b7c0..0b696d82 100755 --- a/native-image/spring-boot-webserver/build-jar-java-base.sh +++ b/native-image/spring-boot-webserver/build-jar-java-base.sh @@ -1,4 +1,4 @@ #!/bin/sh -# Distroless Java 21 (Debian)-provides glibc and other libraries needed by the JDK +# Distroless Java 25 (Debian)-provides glibc and other libraries needed by the JDK docker build --no-cache . -f Dockerfile.distroless-java-base-jar -t webserver:distroless-java-base.jar \ No newline at end of file diff --git a/native-image/spring-boot-webserver/pom.xml b/native-image/spring-boot-webserver/pom.xml index 51561a78..12bca3e6 100644 --- a/native-image/spring-boot-webserver/pom.xml +++ b/native-image/spring-boot-webserver/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6 + 4.0.1 com.example @@ -27,7 +27,7 @@ - 21 + 25 com.example.webserver.WebserverApplication 0.11.1 From ee6e956a8641805d7954cfae177b4095ab33e231 Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Mon, 19 Jan 2026 21:46:22 +0200 Subject: [PATCH 2/3] Upgrade Micronaut webserver to Java 25 --- .../Dockerfile.distroless-base.mostly | 2 +- .../Dockerfile.distroless-java-base-jar | 2 +- .../Dockerfile.distroless-java-base.dynamic | 2 +- ...ile.distroless-java-base.dynamic-optimized | 2 +- ...file.distroless-java-base.dynamic-skipflow | 14 +++ .../Dockerfile.distroless-java-base.jlink | 2 +- .../Dockerfile.eclipse-temurin-jar | 2 +- native-image/micronaut-webserver/README.md | 101 ++++++++++++++++-- .../build-jar-eclipse-temurin.sh | 4 +- .../build-jar-java-base.sh | 2 +- native-image/micronaut-webserver/pom.xml | 6 +- .../Dockerfile.distroless-java-base-jar | 3 +- ...file.distroless-java-base.dynamic-skipflow | 2 +- 13 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-skipflow diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-base.mostly b/native-image/micronaut-webserver/Dockerfile.distroless-base.mostly index 811491ce..7dd5a36c 100644 --- a/native-image/micronaut-webserver/Dockerfile.distroless-base.mostly +++ b/native-image/micronaut-webserver/Dockerfile.distroless-base.mostly @@ -8,7 +8,7 @@ RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -Pmostl # RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -DbuildArgs="--static-nolibc,-Os,-o target/webserver.mostly-static" # Distroless Base - provides glibc -FROM gcr.io/distroless/base-debian12 +FROM gcr.io/distroless/base-debian13 COPY --from=nativebuild /webserver/target/webserver.mostly-static / EXPOSE 8000 ENTRYPOINT ["/webserver.mostly-static", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-java-base-jar b/native-image/micronaut-webserver/Dockerfile.distroless-java-base-jar index 79998e62..e2ba7098 100644 --- a/native-image/micronaut-webserver/Dockerfile.distroless-java-base-jar +++ b/native-image/micronaut-webserver/Dockerfile.distroless-java-base-jar @@ -4,7 +4,7 @@ WORKDIR /webserver RUN ./mvnw --no-transfer-progress clean package # Distoless Java 21 (Debian) -FROM gcr.io/distroless/java21-debian12 +FROM gcr.io/distroless/java25-debian13 COPY --from=build /webserver/target/webserver-0.1.jar webserver-0.1.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "webserver-0.1.jar"] \ No newline at end of file diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic index 251d5df0..2f85b379 100644 --- a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic +++ b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic @@ -5,7 +5,7 @@ WORKDIR /webserver RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image # Distroless Java Base - provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=nativebuild /webserver/target/webserver / EXPOSE 8000 ENTRYPOINT ["/webserver", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-optimized b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-optimized index 9e474c93..b339e0be 100644 --- a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-optimized +++ b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-optimized @@ -8,7 +8,7 @@ RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -Pdynam # RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -DbuildArgs="-Os,-o target/webserver.dynamic-optimized" # Distroless Java Base-provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=nativebuild /webserver/target/webserver.dynamic-optimized / EXPOSE 8000 ENTRYPOINT ["/webserver.dynamic-optimized", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-skipflow b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-skipflow new file mode 100644 index 00000000..48527373 --- /dev/null +++ b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.dynamic-skipflow @@ -0,0 +1,14 @@ +FROM container-registry.oracle.com/graalvm/native-image:25 AS nativebuild +COPY . /webserver +WORKDIR /webserver +# Build a dynamically linked native image with optimization for size +RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -Pdynamic-skipflow-optimized + +# Alternative way to pass Native Image build options with `-DbuildArgs` without using Maven profiles: +# RUN ./mvnw --no-transfer-progress clean package -Dpackaging=native-image -DbuildArgs="-Os,-H:+UnlockExperimentalVMOptions,-H:+TrackPrimitiveValues,-H:+UsePredicates,-o target/webserver.dynamic-skipflow" + +# Distroless Java Base-provides glibc and other libraries needed by the JDK +FROM gcr.io/distroless/java-base-debian13 +COPY --from=nativebuild /webserver/target/webserver.dynamic-skipflow / +EXPOSE 8000 +ENTRYPOINT ["/webserver.dynamic-skipflow", "-b", "0.0.0.0", "-d", "/web"] \ No newline at end of file diff --git a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.jlink b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.jlink index 6f7d3c69..e1a2be21 100644 --- a/native-image/micronaut-webserver/Dockerfile.distroless-java-base.jlink +++ b/native-image/micronaut-webserver/Dockerfile.distroless-java-base.jlink @@ -18,7 +18,7 @@ RUN CP=$(cat cp.txt) && \ --output jlink-jre # Distroless Java Base-provides glibc and other libraries needed by the JDK -FROM gcr.io/distroless/java-base-debian12 +FROM gcr.io/distroless/java-base-debian13 COPY --from=build /webserver/target/webserver-0.1.jar webserver-0.1.jar COPY --from=build /webserver/jlink-jre jlink-jre EXPOSE 8080 diff --git a/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar b/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar index 4de6abcb..f067c109 100644 --- a/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar +++ b/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar @@ -3,7 +3,7 @@ COPY . /webserver WORKDIR /webserver RUN ./mvnw --no-transfer-progress clean package -# Eclipse Temurin Java 25 +# Distoless Java 25 (Debian) FROM eclipse-temurin:25 COPY --from=build /webserver/target/webserver-0.1.jar webserver-0.1.jar EXPOSE 8080 diff --git a/native-image/micronaut-webserver/README.md b/native-image/micronaut-webserver/README.md index 359e620a..415b851c 100644 --- a/native-image/micronaut-webserver/README.md +++ b/native-image/micronaut-webserver/README.md @@ -28,7 +28,7 @@ In this workshop you will: * x86 Linux * `musl` toolchain * Container runtime such as [Docker](https://www.docker.com/gettingstarted/), or [Rancher Desktop](https://docs.rancherdesktop.io/getting-started/installation/) installed and running. -* [GraalVM 25](https://www.graalvm.org/downloads/). We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) +* [Oracle GraalVM 25](https://www.graalvm.org/downloads/). We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) ```bash sdk install java 25-graal ``` @@ -67,7 +67,7 @@ It requires a container image with a JDK and runtime libraries. ### Explanation -The Dockerfile provided for this step pulls [container-registry.oracle.com/graalvm/jdk:24](https://docs.oracle.com/en/graalvm/jdk/24/docs/getting-started/container-images/) for the builder, and then `gcr.io/distroless/java21-debian12` for the runtime. +The Dockerfile provided for this step pulls [container-registry.oracle.com/graalvm/jdk:25](https://docs.oracle.com/en/graalvm/jdk/25/docs/getting-started/container-images/) for the builder, and then `gcr.io/distroless/java25-debian13` for the runtime. The entrypoint for this image is equivalent to `java -jar`, so only a path to a JAR file is specified in `CMD`. ### Action @@ -112,7 +112,7 @@ See how much reduction in size you can gain. Introduced in Java 11, it provides a way to make applications more space efficient and cloud-friendly. The script _build-jlink.sh_ that runs `docker build` using the _Dockerfile.distroless-java-base.jlink_. -The Dockerfile contains two stages: first it generates a `jlink` custom runtime on a full JDK (`container-registry.oracle.com/graalvm/jdk:24`); then copies the runtime image folder along with static assets into a distroless Java base image, and sets the entrypoint. +The Dockerfile contains two stages: first it generates a `jlink` custom runtime on a full JDK (`container-registry.oracle.com/graalvm/jdk:25`); then copies the runtime image folder along with static assets into a distroless Java base image, and sets the entrypoint. Distroless Java base image provides `glibc` and other libraries needed by the JDK, **but not a full-blown JDK**. The application does not have to be modular, but you need to figure out which modules the application depends on to be able to `jlink` it. @@ -238,7 +238,7 @@ In this step, you will build a fully dynamically linked native image **with the GraalVM Native Image provides the option `-Os` which optimizes the resulting native image for file size. `-Os` enables `-O2` optimizations except those that can increase code or executable size significantly. -Learn more about different optimization levels in the [Native Image documentation](https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/#optimization-levels). +Learn more about different optimization levels in the [Native Image documentation](https://www.graalvm.org/jdk25/reference-manual/native-image/optimizations-and-performance/#optimization-levels). To configure the Native Image build and have more manual control over the process, GraalVM provides the [Native Build Tools](https://graalvm.github.io/native-build-tools/latest/index.html): Maven and Gradle plugins for building native images. @@ -315,7 +315,85 @@ No Java Runtime Environment (JRE) is required. The size of the container came down from **132MB** to **102MB**. The executable size decreased by **24MB** (from 86MB to 62MB) just by applying the file size optimization - with no change in behavior or startup time! -## **STEP 5**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container + +## **STEP 5**: (Optional) Build a Size-Optimized Native Image with SkipFlow and Run Inside a Container + +In this step, you will build another fully dynamically linked native image but with the **SkipFlow** and **file size** optimizations on. Then you run it inside a container. + +### Explanation + +As of Oracle GraalVM 25, more performance improvements are enabled by default. +One of which is [SkipFlow](https://www.graalvm.org/release-notes/JDK_25/#native-image)-an extension to the Native Image static analysis that tracks primitive values and evaluates branching conditions dynamically during the process. + +Note: The feature is enabled by default. With the previous releases, it could be controlled using these host options: `-H:+TrackPrimitiveValues` and `-H:+UsePredicates`. + +For this, we have added a separate Maven profile with a different name for the generated native executable: +```xml + + dynamic-skipflow-optimized + + + + org.graalvm.buildtools + native-maven-plugin + + webserver.dynamic-skipflow + + -Os + -H:+UnlockExperimentalVMOptions + -H:+TrackPrimitiveValues + -H:+UsePredicates + + + + + + +``` + +> An alternative way to pass build options to Native Image, without creating Maven profiles, is by using `-DbuildArgs`: +```bash +./mvnw package -Dpackaging=native-image -DbuildArgs="-Os,-H:+UnlockExperimentalVMOptions,-H:+TrackPrimitiveValues,-H:+UsePredicates,-o target/webserver.dynamic-skipflow" +``` + +The Dockerfile for this step, _Dockerfile.distroless-java-base.dynamic-skipflow_, is pretty much the same as before: running a native image build inside the builder container, and then copying it over to a distroless base container with just enough to run the application. +No Java Runtime Environment (JRE) is required. + +### Action + +1. Run the script to build a size-optimized native executable and package it into a container: + ```bash + ./build-dynamic-image-skipflow.sh + ``` + +2. Once the build completes, a container image _distroless-java-base.dynamic-optimized_ should be available. Run it, mapping the ports: + ```bash + docker run --rm -p8080:8080 webserver:distroless-java-base.dynamic-skipflow + ``` + The application is running from the native image inside a container. + The startup time has not changed. + +3. Open a browser and navigate to [localhost:8080/](http://localhost:8080/). You see the GraalVM documentation pages served. + +4. Return to the terminal and stop the running container by clicking CTRL+C. + +5. Check the size of this container image: + ```bash + docker images + ``` + The expected output is: + ```bash + REPOSITORY TAG IMAGE ID CREATED SIZE + webserver distroless-java-base.dynamic-skipflow 6caada87f616 8 minutes ago 101MB + webserver distroless-java-base.dynamic-optimized 5e16a58b1649 10 minutes ago 102MB + webserver distroless-java-base.dynamic d7c449b9373d 12 minutes ago 132MB + webserver distroless-java-base.jlink dde1eb772aa5 15 minutes ago 167MB + webserver distroless-java-base.jar e285476a8266 32 minutes ago 216MB + webserver eclispe-temurin-jar f6eef8d2aa40 33 minutes ago 472MB + ``` + The gain is tiny: the container size reduced only by 1MB, but depending on the application, **SkipFlow can provide up to a 4% reduction in binary size without any additional impact on build time**. + +## **STEP 6**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container In this step, you will build a **mostly static** native image, with the file size optimization on, and then package it into a container image that provides `glibc`, and run. @@ -555,12 +633,13 @@ Note that the website static pages add 44MB to the container images size. Static | Container | Size of a build artefact
(JAR, Jlink runtime, native executable) | Base image | Container | |----------------------------------------|-----------------------------------------------------------------------|------------|-----------| -| eclipse-temurin-jar | webserver-0.1.jar **24MB** | eclipse-temurin:25 201MB | 472MB | -| distroless-java-base.jar | webserver-0.1.jar **24MB** | java21-debian12 192MB | 216MB | -| distroless-java-base.jlink | jlink-jre custom runtime **68MB** | java-base-debian12 128MB | 167MB | -| distroless-java-base.dynamic | webserver.dynamic **86MB** | java-base-debian12 128MB | 132MB | -| distroless-java-base.dynamic-optimized | webserver.dynamic-optimized **62MB** | java-base-debian12 128MB | 102MB | -| distroless-base.mostly-static | webserver.mostly-static **62MB** | base-debian12 48.3MB | 89.7MB | +| eclispe-temurin-jar | webserver-0.1.jar **24MB** | eclipse-temurin:25 201MB | 472MB | +| distroless-java-base.jar | webserver-0.1.jar **24MB** | java25-debian13 192MB | 216MB | +| distroless-java-base.jlink | jlink-jre custom runtime **68MB** | java-base-debian13 128MB | 167MB | +| distroless-java-base.dynamic | webserver.dynamic **86MB** | java-base-debian13 128MB | 132MB | +| distroless-java-base.dynamic-optimized | webserver.dynamic-optimized **62MB** | java-base-debian13 128MB | 102MB | +| distroless-java-base.dynamic-skipflow | webserver.dynamic-skipflow **61MB** | java-base-debian13 128MB | 101MB | +| distroless-base.mostly-static | webserver.mostly-static **62MB** | base-debian13 48.3MB | 89.7MB | | scratch.static | webserver.static **62MB** | scratch 2MB | 69.2MB | | scratch.static-upx | webserver.scratch.static-upx **20MB** | scratch 2MB | 22.3MB | diff --git a/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh b/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh index 82dee3ce..01385fb1 100755 --- a/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh +++ b/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh @@ -1,4 +1,4 @@ #!/bin/sh -# Eclipse Temurin Java 25 -docker build --no-cache . -f Dockerfile.eclipse-temurin-jar -t webserver:eclipse-temurin-jar \ No newline at end of file +# Eclipse-temurin:25 +docker build --no-cache . -f Dockerfile.eclispe-temurin-jar -t webserver:eclispe-temurin-jar diff --git a/native-image/micronaut-webserver/build-jar-java-base.sh b/native-image/micronaut-webserver/build-jar-java-base.sh index d190b7c0..0b696d82 100755 --- a/native-image/micronaut-webserver/build-jar-java-base.sh +++ b/native-image/micronaut-webserver/build-jar-java-base.sh @@ -1,4 +1,4 @@ #!/bin/sh -# Distroless Java 21 (Debian)-provides glibc and other libraries needed by the JDK +# Distroless Java 25 (Debian)-provides glibc and other libraries needed by the JDK docker build --no-cache . -f Dockerfile.distroless-java-base-jar -t webserver:distroless-java-base.jar \ No newline at end of file diff --git a/native-image/micronaut-webserver/pom.xml b/native-image/micronaut-webserver/pom.xml index 3a03d0e5..05a72da9 100644 --- a/native-image/micronaut-webserver/pom.xml +++ b/native-image/micronaut-webserver/pom.xml @@ -19,9 +19,9 @@ jar - 21 - 21 - 4.9.2 + 25 + 25 + 4.8.2 netty false com.example.webserver.Application diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar index 05ecb777..78e4011a 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base-jar @@ -3,8 +3,7 @@ COPY . /webserver WORKDIR /webserver RUN ./mvnw clean package -##### TODO: Upgrade to Distroless Java 25 (Debian) -# Distoless Java 21 (Debian) +# Distoless Java 25 (Debian) FROM gcr.io/distroless/java25-debian13 COPY --from=build /webserver/target/webserver-0.0.1-SNAPSHOT.jar webserver-0.0.1-SNAPSHOT.jar EXPOSE 8080 diff --git a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow index 3107f360..1eac0cbe 100644 --- a/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow +++ b/native-image/spring-boot-webserver/Dockerfile.distroless-java-base.dynamic-skipflow @@ -1,4 +1,4 @@ -FROM container-registry.oracle.com/graalvm/native-image:24 AS nativebuild +FROM container-registry.oracle.com/graalvm/native-image:25 AS nativebuild COPY . /webserver WORKDIR /webserver # Build a dynamically linked native image with optimization for size From 7eeaf643ffd97f4cbba978f00d28cc22f6df7a41 Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Tue, 20 Jan 2026 13:18:30 +0200 Subject: [PATCH 3/3] Update static resources --- ...rin-jar => Dockerfile.eclispe-temurin-jar} | 2 +- native-image/micronaut-webserver/README.md | 2 +- native-image/micronaut-webserver/build-all.sh | 2 +- .../build-jar-eclipse-temurin.sh | 2 +- .../src/main/resources/static.zip | Bin 6283271 -> 6283261 bytes .../build-jar-eclipse-temurin.sh | 2 +- .../src/main/resources/static.zip | Bin 6283271 -> 6283261 bytes 7 files changed, 5 insertions(+), 5 deletions(-) rename native-image/micronaut-webserver/{Dockerfile.eclipse-temurin-jar => Dockerfile.eclispe-temurin-jar} (91%) diff --git a/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar b/native-image/micronaut-webserver/Dockerfile.eclispe-temurin-jar similarity index 91% rename from native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar rename to native-image/micronaut-webserver/Dockerfile.eclispe-temurin-jar index f067c109..4de6abcb 100644 --- a/native-image/micronaut-webserver/Dockerfile.eclipse-temurin-jar +++ b/native-image/micronaut-webserver/Dockerfile.eclispe-temurin-jar @@ -3,7 +3,7 @@ COPY . /webserver WORKDIR /webserver RUN ./mvnw --no-transfer-progress clean package -# Distoless Java 25 (Debian) +# Eclipse Temurin Java 25 FROM eclipse-temurin:25 COPY --from=build /webserver/target/webserver-0.1.jar webserver-0.1.jar EXPOSE 8080 diff --git a/native-image/micronaut-webserver/README.md b/native-image/micronaut-webserver/README.md index 415b851c..0c328968 100644 --- a/native-image/micronaut-webserver/README.md +++ b/native-image/micronaut-webserver/README.md @@ -53,7 +53,7 @@ In this workshop you will: ./build-jar-eclipse-temurin.sh ``` Once the script finishes, a container image _eclipse-temurin-jar_ should be available. - Check its size. It should be **472MB**. + Check its size. It should be **472MB**. ```bash docker images ``` diff --git a/native-image/micronaut-webserver/build-all.sh b/native-image/micronaut-webserver/build-all.sh index 446bd19d..c5efa308 100755 --- a/native-image/micronaut-webserver/build-all.sh +++ b/native-image/micronaut-webserver/build-all.sh @@ -1,7 +1,7 @@ #!/bin/sh -./build-jar-eclipse-temurin.sh ./build-jar-java-base.sh +./build-jar-eclipse-temurin.sh ./build-jlink.sh ./build-dynamic-image.sh ./build-dynamic-image-optimized.sh diff --git a/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh b/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh index 01385fb1..c85d5ae4 100755 --- a/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh +++ b/native-image/micronaut-webserver/build-jar-eclipse-temurin.sh @@ -1,4 +1,4 @@ #!/bin/sh # Eclipse-temurin:25 -docker build --no-cache . -f Dockerfile.eclispe-temurin-jar -t webserver:eclispe-temurin-jar +docker build --no-cache . -f Dockerfile.eclispe-temurin-jar -t webserver:eclipse-temurin-jar diff --git a/native-image/micronaut-webserver/src/main/resources/static.zip b/native-image/micronaut-webserver/src/main/resources/static.zip index 6f620dde7a2af2ff69bea99f37d1a2ec6d8fd4ad..de0fca18936ae8b26db459f854f99cff3230f125 100644 GIT binary patch delta 8542 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 Kmoa3w#Qy*7$=l}2v#6$of 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 Kmoa3w#Qy*7$=l}2v#6$of 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