How to Build a Native Spring Boot Executable with GraalVM and Docker

Learn to compile a Spring Boot 3.5.6 application into a fast-starting native binary using GraalVM, configure the environment, add Maven plugins, write simple test code, and package the result into a lightweight Docker image, achieving dramatically reduced startup time and image size.

Dunmao Tech Hub
Dunmao Tech Hub
Dunmao Tech Hub
How to Build a Native Spring Boot Executable with GraalVM and Docker

Overview

Spring Boot applications are normally packaged as JAR files that require a JRE at runtime, leading to large Docker images and slow startup. GraalVM can compile Java code ahead‑of‑time (AOT) into a native executable, which dramatically reduces both image size and launch time.

Prerequisites

GraalVM distribution based on JDK 21

Maven 3.9.11

Spring Boot 3.5.6

Docker 26.1.4

Environment configuration

Add the following lines to ~/.bashrc (or the appropriate shell profile) and reload the file:

export GRAALVM_HOME=/path/to/graalvm
export JAVA_HOME=$GRAALVM_HOME
export PATH="$JAVA_HOME/bin:$PATH"
source ~/.bashrc

Project setup

The Maven pom.xml defines the Java version, Spring Boot starter, and the GraalVM build plugins.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.uav</groupId>
  <artifactId>springboot-native</artifactId>
  <version>1.0-SNAPSHOT</version>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.6</version>
  </parent>
  <properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.graalvm.buildtools</groupId>
        <artifactId>native-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>com.uav.BootApplication</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Application code

Simple Spring Boot entry point and a REST controller.

package com.uav;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BootApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootApplication.class, args);
    }
}
package com.uav;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @RequestMapping("/users")
    public String getUsers() {
        return "This is a list of users";
    }
}

Build native executable

Compile the project with the native profile. The command produces a native binary in the target directory.

mvn -Pnative native:compile

Docker image

Create a minimal Docker image that contains only the native binary.

FROM ubuntu:jammy
COPY target/springboot-native springboot-native
ENTRYPOINT ["/springboot-native"]

Build and run the image:

docker build . --tag my-app
docker run -p 8080:8080 my-app

Results

The native image starts in roughly 0.065 seconds, and the Docker image size is about 70 % smaller than a traditional JAR‑plus‑JRE image.

GraalVM download screenshot
GraalVM download screenshot
Native binary in target directory
Native binary in target directory
Docker container startup log
Docker container startup log
mavenSpring BootGraalVMnative-image
Dunmao Tech Hub
Written by

Dunmao Tech Hub

Sharing selected technical articles synced from CSDN. Follow us on CSDN: Dunmao.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.