DEV Community

DEV-AI
DEV-AI

Posted on

Best Docker Base Images and Performance Optimization for Java Applications in 2025

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
  • Enable Layered JARs: For faster Docker builds
  # application.yaml
  spring:
    docker:
      compose:
        lifecycle-management: start_and_stop
Enter fullscreen mode Exit fullscreen mode
  • Reactive Stack: Use WebFlux for better resource utilization
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
  </dependency>
Enter fullscreen mode Exit fullscreen mode
  • Virtual Threads (Java 21+): For enhanced throughput
  # application.yaml
  spring:
    threads:
      virtual:
        enabled: true
Enter fullscreen mode Exit fullscreen mode

Best Practices for Containerized Spring Boot

  1. Configure Container Memory Properly
   ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
Enter fullscreen mode Exit fullscreen mode
  1. Use Multi-Stage Builds

    • Reduces image size by separating build and runtime stages
  2. 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
Enter fullscreen mode Exit fullscreen mode
  1. Leverage Spring Boot Actuator
    • Monitor health, metrics, and application state
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>
Enter fullscreen mode Exit fullscreen mode
  1. 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)