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
<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.
Top comments (0)