Selecting the optimal Docker base image for your Java Spring Boot application significantly impacts performance, security, and maintainability. As of May 2025, Java 21 LTS is the recommended version for new production applications, with Java 17 LTS still widely used and fully supported. This article provides current, validated recommendations for Docker base images and performance optimization strategies.
Latest Java Version Status
As of May 2025:
Java 21 LTS: Current long-term support release (released September 2023)
Java 17 LTS: Previous LTS release, fully supported until 2029
Java 25: Latest feature release (non-LTS)
Top Recommended Docker Base Images
Comprehensive Comparison Table
| Base Image | Latest Java Support | Image Size | Startup Time | Security | Memory Usage | OS Base | Best For | Update Cadence |
|---|---|---|---|---|---|---|---|---|
| Eclipse Temurin | Java 21, 17 | 325MB (JDK) 175MB (JRE) | Fast | Excellent | Medium | Ubuntu 22.04 | General use | Weekly |
| Distroless | Java 21, 17 | 110MB | Very Fast | Superior | Low | Debian 12 | High-security prod | Bi-weekly |
| Amazon Corretto | Java 21, 17 | 380MB (JDK) 190MB (JRE) | Fast | Excellent | Medium-High | Amazon Linux 2023 | AWS workloads | Weekly |
| Red Hat UBI | Java 21, 17 | 290MB | Medium | Excellent | Medium | RHEL 9 | Enterprise | Monthly |
| BellSoft Liberica | Java 21, 17 | 320MB (JDK) 160MB (JRE) | Fast | Excellent | Low-Medium | Alpine/Debian | Memory optimization | Weekly |
| GraalVM | Java 21, 17 | 390MB (build) 75MB (native) | Ultra Fast (native) | Excellent | Very Low (native) | Oracle Linux | Native compilation | Monthly |
| Alpine | Java 21, 17 | 120MB | Medium | Good* | Low | Alpine 3.19 | Size-constrained | Variable |
*Alpine poses compatibility risks due to musl libc
Detailed Analysis
1. Eclipse Temurin (Adoptium)
Image:eclipse-temurin:21-jre-jammy(Latest recommendation)
Why Choose It:
- Industry standard with broad adoption and excellent security
- Optimized for containerized environments
- Full Java 21 features with Jakarta EE 10 compatibility
- Example:
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
2. Distroless Java
Image:gcr.io/distroless/java21-debian12
Why Choose It:
- Minimal attack surface (no shell, no package manager)
- Top choice for security-focused deployments
- Example (multi-stage build):
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /build
COPY . .
RUN ./mvnw package -DskipTests
FROM gcr.io/distroless/java21-debian12
COPY --from=builder /build/target/*.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
3. GraalVM Native Images
Image:ghcr.io/graalvm/native-image-community:21
Why Choose It:
- Compiles Java to native executables with near-instant startup
- Up to 50% lower memory footprint
- Best for serverless and microservices
- Example:
FROM ghcr.io/graalvm/native-image-community:21 AS builder
WORKDIR /build
COPY . .
RUN ./mvnw -Pnative native:compile
FROM gcr.io/distroless/base
COPY --from=builder /build/target/myapp /app
ENTRYPOINT ["/app"]
4. BellSoft Liberica
Image:bellsoft/liberica-runtime-container:jre-21-slim-musl
Why Choose It:
- Optimized for memory usage with Alpine variants
- Certified Java SE implementation with Alpine support
5. Amazon Corretto
Image:amazoncorretto:21-al2023-jre
Why Choose It:
- Preferred for AWS deployments
- Optimized for Graviton processors
Spring Boot Performance Optimization
JVM Parameters for Container Environments
-XX:MaxRAMPercentage=75.0 -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+ExitOnOutOfMemoryError -Xshare:on
Spring Boot 3.x-Specific Optimizations
Use Native Compilation: For ultra-fast startup times
# In Maven pom.xml
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
Enable Layered JARs: For faster Docker builds
# application.yaml
spring:
docker:
compose:
lifecycle-management: start_and_stop
Reactive Stack: Use WebFlux for better resource utilization
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Virtual Threads (Java 21+): For enhanced throughput
# application.yaml
spring:
threads:
virtual:
enabled: true
Best Practices for Containerized Spring Boot
Configure Container Memory Properly
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
Use Multi-Stage Builds
- Reduces image size by separating build and runtime stages
Security Hardening
- Run as non-root user
- Remove unnecessary dependencies
- Use read-only filesystems where possible
RUN addgroup --system --gid 1001 appuser && adduser --system --uid 1001 --gid 1001 appuser
USER 1001
Leverage Spring Boot Actuator
- Monitor health, metrics, and application state
- Monitor health, metrics, and application state
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Regularly Scan Images
- Integrate Trivy, Snyk, or Grype into CI/CD pipelines
Recommendation Summary
For General Use: Eclipse Temurin (Java 21 JRE) on Ubuntu
For Highest Security: Distroless Java 21
For Fastest Startup: GraalVM Native Image
For Memory Optimization: BellSoft Liberica on Alpine (after compatibility testing)
For AWS Environments: Amazon Corretto
The Eclipse Temurin images provide the best balance of performance, security, and compatibility for most Spring Boot applications. For applications with specific requirements around startup time or security, consider GraalVM native images or Distroless, respectively.
Regardless of which base image you choose, always apply container-aware JVM settings, implement security best practices, and keep your images updated to protect against emerging vulnerabilities.