Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spring-projects/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

Spring Boot provides two first-class approaches to container image creation: Cloud Native Buildpacks for a zero-Dockerfile workflow, and layered JAR Dockerfiles for full control over image construction. Both approaches produce efficient, cache-friendly OCI images that run on any container runtime.

Cloud Native Buildpacks

Cloud Native Buildpacks (CNB) transform your application source or JAR into a runnable OCI image without requiring you to write a Dockerfile. Spring Boot’s Maven and Gradle plugins include built-in buildpack support, so a single command produces a sensible image and loads it into your local Docker daemon.
The Paketo Spring Boot buildpack supports the layers.idx file, so any layer customization applied to your JAR will be reflected in the image the buildpack creates.
To achieve reproducible builds and container image caching, buildpacks may manipulate application resource metadata such as file “last modified” timestamps. Ensure your application does not rely on that metadata at runtime. Spring Boot uses this information when serving static resources, which can be disabled with the spring.web.resources.cache.use-last-modified property.
1

Verify Docker is running

Buildpacks require a running Docker daemon. Confirm it is accessible before proceeding.
docker info
2

Build the image

Run the build-image goal or task from your project root. Spring Boot’s plugin contacts the Paketo builder, compiles your application, and loads the resulting image into Docker — no Dockerfile required.
./mvnw spring-boot:build-image
3

Run the image

Once the build completes, run the image with Docker:
docker run --rm -p 8080:8080 myapp:0.0.1-SNAPSHOT
For full configuration options — custom image names, builder selection, environment variables passed to buildpacks, and publish settings — see the Maven plugin build-image documentation and the Gradle plugin packaging OCI image documentation.

Dockerfiles with layered JARs

Writing your own Dockerfile gives you precise control over image layers and lets you integrate AOT cache or CDS for faster startup. Spring Boot’s layering feature splits the application into stable and frequently-changing layers so Docker’s build cache is used as effectively as possible.

Why layering matters

Packaging an uber JAR directly into a single Docker layer is simple but wasteful. Library code changes far less often than application code, yet both end up in the same layer. With layered JARs, Spring Boot separates the JAR contents into four standard layers:
LayerContents
dependenciesReleased library JARs
spring-boot-loaderSpring Boot loader classes
snapshot-dependenciesSnapshot library JARs
applicationYour application classes and resources
This means a code-only change rebuilds only the application layer while the three dependency layers are pulled from cache.

Example layers.idx

- "dependencies":
  - BOOT-INF/lib/library1.jar
  - BOOT-INF/lib/library2.jar
- "spring-boot-loader":
  - org/springframework/boot/loader/launch/JarLauncher.class
- "snapshot-dependencies":
  - BOOT-INF/lib/library3-SNAPSHOT.jar
- "application":
  - META-INF/MANIFEST.MF
  - BOOT-INF/classes/a/b/C.class

Building with a Dockerfile

1

Inspect available jarmode commands

The spring-boot-jarmode-tools JAR is automatically added to your repackaged JAR. Use it to explore the extraction options:
java -Djarmode=tools -jar my-app.jar
This prints the available commands:
Usage:
  java -Djarmode=tools -jar my-app.jar

Available commands:
  extract      Extract the contents from the jar
  list-layers  List layers from the jar that can be extracted
  help         Help about any command
2

Write the Dockerfile

Use a multi-stage build. The first stage (builder) extracts the layered JAR, and the second stage copies each layer in dependency order so Docker can cache them independently.
# Builder stage — extract layered JAR contents
FROM eclipse-temurin:21-jre AS builder
WORKDIR /application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=tools -jar application.jar extract --layers --launcher

# Runtime stage — assemble image from extracted layers
FROM eclipse-temurin:21-jre
WORKDIR /application
COPY --from=builder /application/dependencies/ ./
COPY --from=builder /application/spring-boot-loader/ ./
COPY --from=builder /application/snapshot-dependencies/ ./
COPY --from=builder /application/application/ ./
# Start the application jar - this is not the uber jar used by the builder
# This jar only contains application code and references to the extracted jar files
# This layout is efficient to start up and AOT cache (and CDS) friendly
ENTRYPOINT ["java", "-jar", "application.jar"]
If you are using Java 24 or later, use the AOT cache tab. For Java versions below 24, AOT cache is unavailable — use CDS instead.
3

Build the Docker image

With the Dockerfile in the current directory, run:
docker build .
To specify a non-default JAR path:
docker build --build-arg JAR_FILE=path/to/myapp.jar .

Efficient deployments with extracted JARs

Running the application directly from the nested-JAR uber JAR adds a small startup overhead due to classloading from nested archives. For production deployments, extracting the JAR first is recommended.
java -Djarmode=tools -jar my-app.jar extract
Then run the extracted form:
java -jar my-app/my-app.jar
The extracted layout is AOT cache and CDS friendly out of the box. See java -Djarmode=tools -jar my-app.jar help extract for all available extraction options.

Approach comparison

Cloud Native Buildpacks

No Dockerfile required. Single command build. Automatic base image selection and security patching. Best for teams that want a managed, opinionated pipeline.

Layered JAR Dockerfile

Full control over base image and build steps. Supports AOT cache and CDS training runs inline. Best for teams with existing Docker workflows or specific image requirements.

Build docs developers (and LLMs) love