Containers provide the flexibility of development environments to match a production environment, to help isolate your application, and to minimize overhead. For self-contained executables, generated with GraalVM Native Image, containers are an obvious deployment choice.
To support container-based development, there are several GraalVM container images available, depending on the platform, the architecture, the Java version, and the edition:
This guide shows how to containerize a native executable for your Java application. You will use a GraalVM container image with Native Image to compile a Java application ahead-of-time into a native executable.
This guide uses the Spring Boot 3 Native Image Microservice example.
The example is a minimal REST-based API application, built on top of Spring Boot 3.
If you call the HTTP endpoint /jibber
, it will return some nonsense verse generated in the style of the Jabberwocky poem, by Lewis Carroll.
Make sure you have installed a GraalVM JDK. The easiest way to get started is with SDKMAN!. For other installation options, visit the Downloads section.
Install and run a Docker-API compatible container runtime such as Rancher Desktop, Docker, or Podman.
git clone https://github.com/graalvm/graalvm-demos.git
cd graalvm-demos/native-image/containerize/spring-boot-microservice-jibber
With the built-in support for GraalVM Native Image in Spring Boot 3, it has become much easier to compile a Spring Boot 3 application into a native executable.
./mvnw native:compile -Pnative
The -Pnative
profile is used to generate a native executable for your platform.
This will generate a native executable called benchmark-jibber in the target/ directory.
&
:
./target/benchmark-jibber &
curl
:
curl http://localhost:8080/jibber
You should get a random nonsense verse.
fg
, and then enter <CTRL-c>
to stop the application.The generated native executable is platform-dependent.
Containerize the native executable using the following commands.
docker build -f Dockerfiles/Dockerfile.native --build-arg APP_FILE=benchmark-jibber -t jibber-benchmark:native.0.0.1-SNAPSHOT .
docker build -f Dockerfiles/Dockerfile -t jibber-benchmark:native.0.0.1-SNAPSHOT .
docker run --rm --name native -p 8080:8080 jibber-benchmark:native.0.0.1-SNAPSHOT
curl
:
curl http://localhost:8080/jibber
It should generate a random nonsense verse.
docker ps
, and then run:
docker rm -f <container_id>
docker images
, and then run:
docker rmi -f <image_1_id> <image_n_id>
In this guide, you saw how to use GraalVM container images to containerize a native executable for your Java application.
With GraalVM Native Image you can also build fully static native executables and package them directly into tiny containers such as scratch or distroless containers.