Skip to content

Commit 6bfdf67

Browse files
committed
Make step buiding with Paketo Buildpacks optional and requiring GraalVM for JDK 21
1 parent 9e853a9 commit 6bfdf67

File tree

1 file changed

+70
-68
lines changed

1 file changed

+70
-68
lines changed

native-image/spring-boot-webserver/README.md

+70-68
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Multicloud Apps with GraalVM - Up and Running
22

3-
This workshop is for developers looking to understand how to **build size-optimized cloud native Java applications** using [GraalVM Native Image](https://www.graalvm.org/jdk21/reference-manual/native-image/).
3+
This workshop is for developers looking to understand how to **build size-optimized cloud native Java applications** using [GraalVM Native Image](https://www.graalvm.org/jdk23/reference-manual/native-image/).
44

55
In this workshop, you will discover ways to minimize application footprint using different Native Image linking options and packaging into various base containers. You will run a Spring Boot web server application hosting the GraalVM documentation website.
66

@@ -24,7 +24,6 @@ In this workshop you will:
2424
* `musl` toolchain
2525
* Container runtime such as [Rancher Desktop](https://docs.rancherdesktop.io/getting-started/installation/) or [Docker](https://www.docker.com/gettingstarted/) installed and running
2626
* [GraalVM for JDK 23](https://www.graalvm.org/downloads/) or later. We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).)
27-
2827
```bash
2928
sdk install java 23-graal
3029
```
@@ -133,67 +132,7 @@ The `ENTRYPOINT` for the application would be `java` from the custom runtime.
133132
```
134133
Jlink shrank the container by **46MB**.
135134

136-
## **STEP 3**: Build and Run a Native Image Inside a Container Using Paketo Buildpacks
137-
138-
In this step, you will compile this Spring Boot application ahead of time with GraalVM Native Image and run it using Paketo Buildpacks container images.
139-
140-
### Explanation
141-
142-
Spring Boot supports building a native image in a container using the [Paketo Buildpack for Oracle](https://github.com/paketo-buildpacks/oracle) which provides Oracle GraalVM Native Image.
143-
144-
The Paketo builder pulls the [Jammy Tiny Stack image](https://github.com/paketo-buildpacks/builder-jammy-tiny) (Ubuntu distroless-like image) which contains no buildpacks.
145-
Then you point the **builder** image to the **creator** image.
146-
For this workshop, you point to the [Paketo Buildpack for Oracle](https://github.com/paketo-buildpacks/oracle) explicitly requesting the Native Image tool.
147-
148-
If you open the _pom.xml_ file, you see the `spring-boot-maven-plugin` declaration added for you:
149-
```xml
150-
<configuration>
151-
<image>
152-
<builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder>
153-
<buildpacks>
154-
<buildpack>paketobuildpacks/oracle</buildpack>
155-
<buildpack>paketobuildpacks/java-native-image</buildpack>
156-
</buildpacks>
157-
</image>
158-
</configuration>
159-
```
160-
When `java-native-image` is requested, the buildpack downloads Oracle GraalVM, which includes Native Image.
161-
The [Paketo documentation provides several examples](https://paketo.io/docs/howto/java/#build-an-app-as-a-graalvm-native-image-application) that show you how to build applications with Native Image using buildpacks.
162-
163-
> Note that if you do not specify Oracle's buildpack, it will pull the default buildpack, which can result in reduced performance.
164-
165-
### Action
166-
167-
1. Build a native executable for this Spring application using the Paketo buildpack:
168-
```bash
169-
./mvnw -Pnative spring-boot:build-image
170-
```
171-
172-
2. Once the build completes, a container image _0.0.1-SNAPSHOT_ should be available. Run it, mapping the ports:
173-
```bash
174-
docker run --rm -p8080:8080 docker.io/library/webserver:0.0.1-SNAPSHOT
175-
```
176-
177-
The application is running from the native image inside a container. The container started in just **0.031 seconds**!
178-
179-
3. Open a browser and navigate to [localhost:8080/](http://localhost:8080/). You see the GraalVM documentation pages served.
180-
181-
4. Return to the terminal and stop the running container by clicking CTRL+C.
182-
183-
5. Check the size of this container image:
184-
```bash
185-
docker images
186-
```
187-
The expected output is:
188-
```
189-
REPOSITORY TAG IMAGE ID CREATED SIZE
190-
webserver distroless-java-base.jlink 687f7683ad58 31 minutes ago 192MB
191-
webserver debian-slim.jar 5c69f06a3972 2 hours ago 238MB
192-
webserver 0.0.1-SNAPSHOT 0660806da4a2 44 years ago 163MB
193-
```
194-
The new container, tagged as _0.0.1-SNAPSHOT_, is much smaller now **163MB**.
195-
196-
## **STEP 4**: Build a Native Image Locally and Run Inside a Container (Default Configuration)
135+
## **STEP 3**: Build a Native Image Locally and Run Inside a Container (Default Configuration)
197136

198137
In this step, you will create a native image with the default configuration on a host machine, and only run it inside a container.
199138

@@ -256,7 +195,7 @@ Learn more in ["Distroless" Container Images](https://github.com/GoogleContainer
256195
The expected size is **125M**.
257196
Note that the static resources are "baked" into this native executable and added 44M to its size.
258197

259-
## **STEP 5**: Build a Size-Optimized Native Image Locally and Run Inside a Container
198+
## **STEP 4**: Build a Size-Optimized Native Image Locally and Run Inside a Container
260199

261200
_This is where the fun begins._
262201

@@ -342,7 +281,7 @@ The script _build-dynamic-image.sh_, available in this repository for your conve
342281

343282
The size decreased from **125M** (`webserver`) to **92M** (`webserver.dynamic-optimized`) by applying the file size optimization.
344283

345-
## **STEP 6**: Build a Size-Optimized Mostly Static Native Image Locally and Run Inside a Container
284+
## **STEP 5**: Build a Size-Optimized Mostly Static Native Image Locally and Run Inside a Container
346285

347286
In this step, you will build a **mostly static** native image, with the file size optimization on, on a host machine, then package it into a container image that provides `glibc`, and run.
348287

@@ -428,7 +367,7 @@ A separate Maven profile exists for this step:
428367
429368
The size of the mostly static native image (`webserver.mostly-static`) has not changed much, and is around **93MB**.
430369
431-
## **STEP 7**: Build a Size-Optimized Fully Static Native Image Locally and Run Inside a Container
370+
## **STEP 6**: Build a Size-Optimized Fully Static Native Image Locally and Run Inside a Container
432371
433372
In this step, you will build a **fully static** native image, with the file size optimization on, on a host machine, then package it into a _scratch_ container.
434373
@@ -528,7 +467,7 @@ A separate Maven profile exists for this step:
528467
529468
The size of the mostly static native image (`webserver.static`) has not changed, and is around **93MB**.
530469
531-
## **STEP 8**: Compress a Static Native Image with UPX and Run Inside a Container
470+
## **STEP 7**: Compress a Static Native Image with UPX and Run Inside a Container
532471
533472
_What can you do next to reduce the size even more?_
534473
@@ -594,7 +533,70 @@ It can significantly reduce the executable size, but note, that UPX loads the ex
594533
The container size reduced dramatically to just **36.2MB**.
595534
The application and container image's size have been shrunk to the minimum.
596535

597-
## **STEP 9**: Clean up (Optional)
536+
## **STEP 8**: (Optional) Build and Run a Native Image Inside a Container Using Paketo Buildpacks
537+
538+
You can also compile this Spring Boot application ahead of time with GraalVM Native Image and run it using Paketo Buildpacks container images.
539+
540+
> Prerequisite: [GraalVM for JDK 21](https://www.graalvm.org/downloads/). We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).)
541+
```bash
542+
sdk install java 21-graal
543+
```
544+
545+
### Explanation
546+
547+
Spring Boot supports building a native image in a container using the [Paketo Buildpack for Oracle](https://github.com/paketo-buildpacks/oracle) which provides Oracle GraalVM Native Image.
548+
549+
The Paketo builder pulls the [Jammy Tiny Stack image](https://github.com/paketo-buildpacks/builder-jammy-tiny) (Ubuntu distroless-like image) which contains no buildpacks.
550+
Then you point the **builder** image to the **creator** image.
551+
For this workshop, you point to the [Paketo Buildpack for Oracle](https://github.com/paketo-buildpacks/oracle), explicitly requesting the Native Image tool.
552+
553+
If you open the _pom.xml_ file, you see the `spring-boot-maven-plugin` declaration added for you:
554+
```xml
555+
<configuration>
556+
<image>
557+
<builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder>
558+
<buildpacks>
559+
<buildpack>paketobuildpacks/oracle</buildpack>
560+
<buildpack>paketobuildpacks/java-native-image</buildpack>
561+
</buildpacks>
562+
</image>
563+
</configuration>
564+
```
565+
When `java-native-image` is requested, the buildpack downloads Oracle GraalVM, which includes Native Image.
566+
The [Paketo documentation provides several examples](https://paketo.io/docs/howto/java/#build-an-app-as-a-graalvm-native-image-application) that show you how to build applications with Native Image using buildpacks.
567+
568+
> Note that if you do not specify Oracle's buildpack, it will pull the default buildpack, which can result in reduced performance.
569+
570+
### Action
571+
572+
1. Build a native executable for this Spring application using the Paketo buildpack:
573+
```bash
574+
./mvnw -Pnative spring-boot:build-image
575+
```
576+
577+
2. Once the build completes, a container image _0.0.1-SNAPSHOT_ should be available. Run it, mapping the ports:
578+
```bash
579+
docker run --rm -p8080:8080 docker.io/library/webserver:0.0.1-SNAPSHOT
580+
```
581+
582+
The application is running from the native image inside a container. The container started in **0.031 seconds**.
583+
584+
3. Open a browser and navigate to [localhost:8080/](http://localhost:8080/). You see the GraalVM documentation pages served.
585+
586+
4. Return to the terminal and stop the running container by clicking CTRL+C.
587+
588+
5. Check the size of this container image:
589+
```bash
590+
docker images
591+
```
592+
The expected output is:
593+
```
594+
REPOSITORY TAG IMAGE ID CREATED SIZE
595+
webserver 0.0.1-SNAPSHOT 0660806da4a2 44 years ago 163MB
596+
```
597+
The new container, tagged as _0.0.1-SNAPSHOT_, is **163MB**.
598+
599+
## **STEP 9**: (Optional) Clean up
598600
599601
To clean up all images, run the `./clean.sh` script provided for that purpose.
600602

0 commit comments

Comments
 (0)