Spring Boot Dockerfile generator
Get a multi-stage Dockerfile with cached dependencies, layered jars, a small JRE image, a non-root user and sensible JVM memory flags.
A production-minded Dockerfile for Spring Boot
The two-line Dockerfile in many tutorials (COPY app.jar and java -jar) works, but it rebuilds the whole image on every change, runs as root, includes the JDK, and gives the JVM no hint about container memory. This generator writes the version you would want in production: a multi-stage build with cached dependency downloads, an optional layered jar, a small JRE runtime image, a non-root user, container-aware memory settings and a signal-friendly entrypoint.
Pick Java 17, 21 or 25 and Maven or Gradle, say which Spring Boot generation you use, and copy the result. The Boot version matters in two places: Spring Boot 3.3 introduced -Djarmode=tools for layer extraction (older versions use layertools), and the launcher class moved to org.springframework.boot.loader.launch in 3.2. The tool picks the right pair for you.
Choices explained
- Build cache mounts (
RUN --mount=type=cache) keep the Maven or Gradle download cache between builds. They need BuildKit, the default in current Docker. - MaxRAMPercentage sizes the heap from the container limit instead of the host's memory.
- JRE image: eclipse-temurin JRE images are smaller than the JDK ones. The Alpine variants use musl libc; stay on the default Ubuntu-based tag unless you have tested Alpine.
- No HEALTHCHECK is included because a JRE image may lack curl or wget. In Kubernetes use readiness and liveness probes on
/actuator/health.
The output is a starting point: adjust file paths for multi-module projects and review it before using it in your pipeline. Nothing is uploaded; the file is generated in your browser.
Frequently asked questions
What are layered jars and why use them?
A Spring Boot jar can be split into layers (dependencies, loader, snapshot dependencies, application code). Docker caches each layer, so when only your code changes, only the small application layer is rebuilt and pushed, not 80 MB of libraries.
Why a multi-stage build?
The first stage has the JDK and Maven or Gradle to compile the project; the final stage has only a JRE and your jar. The image is smaller and does not ship build tools or source code.
Why run as a non-root user?
If the application is compromised, a non-root process has far fewer ways to damage the container or the host. Some platforms, such as OpenShift, require it.
Why exec java in the entrypoint?
With exec the JVM replaces the shell and becomes PID 1, so Docker and Kubernetes signals (SIGTERM) reach Java and Spring can shut down gracefully. Without it the shell swallows the signal.