You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: native-image/micronaut-webserver/README.md
+91-12Lines changed: 91 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,7 +28,7 @@ In this workshop you will:
28
28
* x86 Linux
29
29
*`musl` toolchain
30
30
* Container runtime such as [Docker](https://www.docker.com/gettingstarted/), or [Rancher Desktop](https://docs.rancherdesktop.io/getting-started/installation/) installed and running.
31
-
*[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/).)
31
+
*[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/).)
32
32
```bash
33
33
sdk install java 25-graal
34
34
```
@@ -53,7 +53,7 @@ In this workshop you will:
53
53
./build-jar-eclipse-temurin.sh
54
54
```
55
55
Once the script finishes, a container image _eclipse-temurin-jar_ should be available.
56
-
Check its size. It should be **472MB**.
56
+
Check its size. It should be **472MB**.
57
57
```bash
58
58
docker images
59
59
```
@@ -67,7 +67,7 @@ It requires a container image with a JDK and runtime libraries.
67
67
68
68
### Explanation
69
69
70
-
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.
70
+
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.
71
71
The entrypoint forthis image is equivalent to `java -jar`, so only a path to a JAR file is specifiedin`CMD`.
72
72
73
73
### Action
@@ -112,7 +112,7 @@ See how much reduction in size you can gain.
112
112
Introduced in Java 11, it provides a way to make applications more space efficient and cloud-friendly.
113
113
114
114
The script _build-jlink.sh_ that runs `docker build` using the _Dockerfile.distroless-java-base.jlink_.
115
-
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.
115
+
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.
116
116
Distroless Java base image provides `glibc` and other libraries needed by the JDK, **but not a full-blown JDK**.
117
117
118
118
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
238
238
239
239
GraalVM Native Image provides the option `-Os` which optimizes the resulting native image for file size.
240
240
`-Os` enables `-O2` optimizations except those that can increase code or executable size significantly.
241
-
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).
241
+
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).
242
242
243
243
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.
244
244
@@ -315,7 +315,85 @@ No Java Runtime Environment (JRE) is required.
315
315
The size of the container came down from **132MB** to **102MB**.
316
316
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!
317
317
318
-
## **STEP 5**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container
318
+
319
+
## **STEP 5**: (Optional) Build a Size-Optimized Native Image with SkipFlow and Run Inside a Container
320
+
321
+
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.
322
+
323
+
### Explanation
324
+
325
+
As of Oracle GraalVM 25, more performance improvements are enabled by default.
326
+
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.
327
+
328
+
Note: The feature is enabled by default. With the previous releases, it could be controlled using these host options: `-H:+TrackPrimitiveValues` and `-H:+UsePredicates`.
329
+
330
+
For this, we have added a separate Maven profile with a different name for the generated native executable:
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.
360
+
No Java Runtime Environment (JRE) is required.
361
+
362
+
### Action
363
+
364
+
1. Run the script to build a size-optimized native executable and package it into a container:
365
+
```bash
366
+
./build-dynamic-image-skipflow.sh
367
+
```
368
+
369
+
2. Once the build completes, a container image _distroless-java-base.dynamic-optimized_ should be available. Run it, mapping the ports:
370
+
```bash
371
+
docker run --rm -p8080:8080 webserver:distroless-java-base.dynamic-skipflow
372
+
```
373
+
The application is running from the native image inside a container.
374
+
The startup time has not changed.
375
+
376
+
3. Open a browser and navigate to [localhost:8080/](http://localhost:8080/). You see the GraalVM documentation pages served.
377
+
378
+
4. Return to the terminal and stop the running container by clicking CTRL+C.
379
+
380
+
5. Check the size of this container image:
381
+
```bash
382
+
docker images
383
+
```
384
+
The expected output is:
385
+
```bash
386
+
REPOSITORY TAG IMAGE ID CREATED SIZE
387
+
webserver distroless-java-base.dynamic-skipflow 6caada87f616 8 minutes ago 101MB
388
+
webserver distroless-java-base.dynamic-optimized 5e16a58b1649 10 minutes ago 102MB
389
+
webserver distroless-java-base.dynamic d7c449b9373d 12 minutes ago 132MB
390
+
webserver distroless-java-base.jlink dde1eb772aa5 15 minutes ago 167MB
391
+
webserver distroless-java-base.jar e285476a8266 32 minutes ago 216MB
392
+
webserver eclispe-temurin-jar f6eef8d2aa40 33 minutes ago 472MB
393
+
```
394
+
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**.
395
+
396
+
## **STEP 6**: Build a Size-Optimized Mostly Static Native Image and Run Inside a Container
319
397
320
398
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.
321
399
@@ -555,12 +633,13 @@ Note that the website static pages add 44MB to the container images size. Static
555
633
556
634
| Container | Size of a build artefact <br> (JAR, Jlink runtime, native executable) | Base image | Container |
0 commit comments