Skip to content

Migrate Dockerfile to Docker Hardened Images (DHI) #306

@nanotaboada

Description

@nanotaboada

Problem

The current Dockerfile uses maven:3.9-eclipse-temurin-25-alpine (builder) and eclipse-temurin:25-jdk-alpine (runtime). Using the full JDK at runtime ships compiler tooling, javac, jshell, and debug utilities that are never used, unnecessarily inflating the image and the attack surface.

Pain points with the current approach:

  • Full JDK at runtime is the primary driver of Java's large image size in this comparison study
  • Known CVEs in base images requiring constant monitoring
  • No built-in SBOM, provenance attestations, or SLSA compliance
  • Manual security update maintenance

Proposed Solution

Migrate to Docker Hardened Images (DHI), using a JRE-based runtime image (not JDK) to reduce both attack surface and image size in a single step.

DHI provides:

  • Up to 95% reduction in attack surface vs. standard images
  • Near-zero CVEs, actively maintained by Docker's security team
  • Built-in SBOM, provenance attestations, SLSA Build Level 3
  • Free and open source (Apache 2.0)

Suggested Approach

1. Update base images

Builder stage:

# Replace:
FROM maven:3.9-eclipse-temurin-25-alpine AS builder

# With:
FROM dhi.io/eclipse-temurin:25-jdk-alpine-dev AS builder

Runtime stage:

# Replace:
FROM eclipse-temurin:25-jdk-alpine AS runtime

# With:
FROM dhi.io/eclipse-temurin:25-jre-alpine AS runtime

Switching from jdk to jre in the runtime is a direct size win bundled into this migration. For an even smaller image, see the dedicated jlink issue.

2. Adapt health check

Verify curl availability in the DHI Alpine JRE variant. If unavailable:

Option A: Replace with a Java-based HTTP check in healthcheck.sh.
Option B: Explicitly install curl via apk add --no-cache curl.

3. Key files to modify

  • Dockerfile — update base images, verify apk add curl compatibility
  • scripts/healthcheck.sh — adapt if removing curl dependency
  • .github/workflows/maven.yml — update CI/CD if dhi.io authentication is needed

4. Architecture considerations

  • Multi-stage build preserved
  • Non-root spring user maintained
  • /storage volume mount unchanged
  • SQLite runtime libs (sqlite-libs) still required via apk
  • No application code changes required

Note: relationship to other Docker optimization issues

This issue focuses on security hardening. The jlink issue addresses the primary size reduction (full JDK → custom minimal JRE). Both can be implemented independently; jlink provides deeper size savings than the JDK→JRE switch bundled here.

Acceptance Criteria

  • Application builds successfully using DHI base images
  • All existing endpoints function identically
  • Container starts, serves on port 9000/9001, and stops correctly
  • Health check passes consistently
  • Volume mount (/storage) works correctly
  • Non-root user (spring) has correct permissions
  • Docker Scout scan shows significantly reduced CVE count vs. previous image
  • SBOM is present and complete (docker buildx imagetools inspect --format "{{json .SBOM}}")
  • Provenance attestations are verifiable
  • All CI tests pass against the new image

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    containersPull requests that update containers codeenhancementNew feature or requestjavaPull requests that update Java codepriority lowNice-to-have improvement. Can be deferred without blocking other work.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions