Making the Most of Your Docker Hardened Images Trial – Part 1

投稿日 11月 14, 2025

First steps: Run your first secure, production-ready image

Container base images form the foundation of your application security. When those foundations contain vulnerabilities, every service built on top inherits the same risk. 

Docker Hardened Images addresses this at the source. These are continuously-maintained, minimal base images designed for security: stripped of unnecessary packages, patched proactively, and built with supply chain attestation. Instead of maintaining your own hardened bases or accepting whatever vulnerabilities ship with official images, you get production-ready foundations with near-zero CVEs and compliance metadata baked in.

What to Expect from Your 30-days Trial?

You’ve got 30 days to evaluate whether Docker Hardened Images fits your environment. That’s enough time to answer the crucial question: Would this reduce our security debt without adding operational burden?

It’s important to note that while DHI provides production‑grade images, this trial isn’t about rushing into production. Its primary purpose is educational: to let you experience the benefits of a hardened base image for supply‑chain security by testing it with the actual services in your stack and measuring the results.

By the end of the trial, you should have concrete results

  • CVE counts before and after, 
  • engineering effort required per image migration, and
  • whether your team would actually use this. 

Testing with real projects always outshines promises.

The DHI quickstart guide walks through the actions. This post covers what the docs don’t: the confusion points you may hit, what metrics actually matter, and how to evaluate results easily.

Step 1: Understanding the DHI Catalog 

To get started with your Free trial, you must be an organization owner or editor. This means you will get your own Repository where you can mirror images, but we’ll get back to this later.

If you are familiar with Docker Hub, the DHI catalog should already look familiar:

DHI Trial 4 1

The most obvious difference are the little lock icons indicating a Hardened Image. But what exactly does it mean?
The core concept behind hardened images is that they present a minimal attack surface, which in practical terms means that only the strict minimum is included (as opposed to “battery-included” distributions like Ubuntu or Debian). 
Think of it like this: The hardened images maintain compatibility with the distro’s core characteristics (libc, filesystem hierarchy, package names) while removing the convenience layers that increase attack surface (package managers, extra utilities, debugging tools).
So the “OS” designation you can see below every DHI means this image is built on top of those  distributions (uses the same base operating system), but with security hardening and package minimization applied.

DHI Trial 3

Sometimes, you need these convenient Linux utilities, for development or testing purposes. 
This is where variants come into play.

DHI Trial 2

The catalog shows multiple variants for each base image: standard versions, (dev) versions, (fips) versions. 
The variant choice matters for security posture. If you can run your application without a package manager in the final image (using multi-stage builds, for example), always choose the standard variant. Fewer tools in the container means fewer potential vulnerabilities.
Here’s what they mean: 
Standard variants (e.g., node-base:24-debian13):

  • Minimal runtime images
  • No package managers (apk, apt, yum removed)
  • Production-ready
  • Smallest attack surface

Fips variants (e.g., node-base:24-debian13-fips):
FIPS variants come in both runtime and build-time variants. These variants use cryptographic modules that have been validated under FIPS 140, a U.S. government standard for secure cryptographic operations. They are required for highly-regulated environments

Dev variants (e.g., node-base:24-debian13-dev):

  • Include package managers for installing additional dependencies
  • Useful during development or when you need to add packages at build time
  • Larger attack surface (but still hardened)
  • Not recommended for production

The catalog includes dozens of base images: language runtimes (Python, Node, Go), distros (Alpine, Ubuntu, Debian), specialized tools (nginx, Redis). 
Instead of trying to evaluate everything from the start, start narrow by picking one image (that you use frequently (Alpine, Python, Node are common starting points) for the first test.
What “Entitlements” and “Mirroring” Actually Mean
You can’t just ‘docker pull’ directly from Docker’s DHI catalog. Instead, you mirror images to your organization’s namespace first. Here’s the workflow:

  1. Your trial grants your organization access to a certain number of DHIs through mirroring: these are called entitlements.
  2. As an organization owner, you first create a copy of the DHI image in your namespace (e.g., yourorg/dhi-node), which means you are mirroring the image and will automatically receive new updates in your repository.
  3. Your team pulls from your org’s namespace, not Docker’s.

Mirroring takes a few minutes and copies all available tags. Once complete, the image appears in your organization’s repositories like any other image.
Why this model? Two reasons:

  • Access control: Your org admins control which hardened images your team can use
  • Availability: Mirrored images remain available even if your subscription changes

The first time you encounter “mirror this image to your repository,” it feels like unnecessary friction. But once you realize it’s a one-time setup per base image (not per tag), it makes sense. You mirror node-base once and get access to all current and future Node versions
Now that you’ve mirrored a hardened image, it’s time to test it with an actual project. The goal is to discover friction points early, when stakes are low.

DHI Trial 1


Step 2: Your First Real Migration Test

Choose a project that is:

  • Simple enough to debug quickly if something breaks (fewer moving parts)
  • Real enough to represent actual workloads
  • Representative of your stack

Drop-In Replacement


Open your Dockerfile and locate the FROM instruction. The migration is straightforward:

# Before
FROM node:22-bookworm-slim
# After
FROM <your-org-namespace>/dhi-node:22-debian13-fips

Replace your organization’s namespace and choose the appropriate tag. If you were using a generic tag like node:22, switch to a specific version tag from the hardened catalog (like 22-debian13-fips). Pinning to specific versions is a best practice anyway – hardened images just make it more explicit.

For other language runtimes, the pattern is similar:

# Python example
FROM python:3.12-slim
# becomes
FROM <your-org-namespace>/dhi-python-base:3.12-bookworm

# Node example
FROM node:20-alpine
# becomes
FROM <your-org-namespace>/dhi-node-base:20.18-alpine3.20


Build the image with your new base:

docker build . -t my-service-hardened

Watch the build output: if your Dockerfile assumes certain utilities exist (like wget, curl, or package managers), the build may fail. This is expected. Hardened bases strip unnecessary tools to reduce attack surface. Here are some common build failures and fixes:

Missing package manager (apt, yum):

  • If you’re installing packages in your Dockerfile, you’ll need to use the (dev) variant, and probably switch to a multi-stage build (install dependencies in a builder stage using a dev variant, then copy artifacts to the minimal runtime stage use a fips hardened base image variant)


Missing utilities (wget, curl, bash):

  • Network tools are removed unless you’re using a debug variant
  • Solution: same as above, install what you need explicitly in a builder stage, or verify you actually need those tools at runtime

Different default user:

  • Some hardened images run as non-root by default
  • If your application expects to write to certain directories, you may need to adjust permissions or use USER directives appropriately

For my Node.js test, the build succeeded without changes. The hardened Node base contained everything the runtime needed – npm dependencies installed normally, and the packages removed were system utilities my application never touched.


Verify It Runs


Build success doesn’t mean runtime success. Start the container and verify it behaves correctly:

docker run --rm -p 3000:3000 my-service-hardened

Test the service:

  • Does it start without errors?
  • Do API endpoints respond correctly?
  • Are logs written as expected?
  • Can it connect to databases or external services?


Step 3: Comparing What Changed

Before moving to measurement, build the original version alongside the hardened one:

# Switch to your main branch
git checkout main
# Build original version
docker build . -t my-service-original
# Switch back to your test branch with hardened base
git checkout dhi-test
# Build hardened version
docker build . -t my-service-hardened


Now you have two images to compare: one with the official base, one with the hardened base. Now comes the evaluation: what actually improved, and by how much?

ドッカースカウト

Docker Scout compares images and reports on vulnerabilities, package differences, and size changes. If you haven’t enrolled your organization with Scout yet, you’ll need to do that first (it’s free for the comparison features we’re using).


Run the comparison (here we are comparing Node base images) :

docker scout compare --to <your-org-namespace>/dhi-node:24.11-debian13-fips node:24-bookworm-slim

Scout outputs a detailed breakdown. Here’s what we found when comparing the official Node.js image to the hardened version.


1. Vulnerability Reduction


The Scout output shows CVE counts by severity:

                     Official Node          Hardened DHI
                      24-bookworm-slim       24.11-debian13-fips
Critical              0                      0
High                  0                      0
Medium                1                      0  ← eliminated
Low                   24                     0  ← eliminated
Total                 25                     0


The hardened image achieved complete vulnerability elimination. While the official image already had zero Critical/High CVEs (good baseline), it contained 1 Medium and 24 Low severity issues – all eliminated in the hardened version.
Medium and Low severity vulnerabilities matter for compliance frameworks. If you’re pursuing SOC2, ISO 27001, or similar certifications (especially in regulated industries with strict security standards), demonstrating zero CVEs across all severity levels significantly simplifies audits.


2. Package Reduction 


Scout shows a dramatic difference in package count:

                     Official Node          Hardened DHI
Total packages        321                    32
Reduction             —                      289 packages (90%)


The hardened image removed 289 packages including:

  • apt (package manager)
  • gcc-12 (entire compiler toolchain)
  • perl (scripting language)
  • bash (replaced with minimal shell)
  • dpkg-dev (Debian package tools)
  • gnupg2, gzip, bzip2 (compression and crypto utilities)
  • dozens of libraries and system utilities


These are tools your Node.js application never uses at runtime. Removing them drastically reduces attack surface: 90% fewer packages means 90% fewer potential targets for exploitation.
This is important because even if packages have no CVEs today, they represent future risk. Every utility, library, or tool in your image could become a vulnerability tomorrow. The hardened base eliminates that entire category of risk.


3. Size Difference


Scout reports image sizes:

                     Official Node          Hardened DHI
Image size            82 MB                  48 MB
Reduction             —                      34 MB (41.5%)


The hardened image is 41.5% smaller – that’s 34 MB saved per image. For a single service, this might seem minor. But multiply across dozens or hundreds of microservices, and the benefits start to become obvious: faster pulls, lower storage costs, and reduced network transfer.


4. Extracting and Reading the SBOM

One of the most valuable compliance features is the embedded SBOM (Software Bill of Materials). Unlike many images where you’d need to generate the SBOM yourself, hardened images include it automatically.


Extract the SBOM to see every package in the image:

docker scout sbom <your-org-namespace>/dhi-node:24.11-debian13-fips --format list

This outputs a complete package inventory:

Name                  Version          Type
base-files            13.8+deb13u1     deb
ca-certificates       20250419         deb
glibc                 2.41-12          deb
nodejs                24.11.0          dhi
openssl               3.5.4            dhi
openssl-provider-fips 3.1.2            dhi
...


The Type column shows where packages came from:

  • deb: Debian system packages
  • dhi: Docker Hardened Images custom packages (like FIPS-certified OpenSSL)
  • docker: Docker-managed runtime components

The SBOM includes name, version, license, and package URL (purl) for each component – everything needed for vulnerability tracking and compliance reporting.
You can can easily the SBOM in SPDX or CycloneDX format for ingestion by a vulnerability tracking tools:

# SPDX format (widely supported)
docker scout sbom <your-org>/dhi-node:24.11-debian13-fips \
  --format spdx \
  --output node-sbom.json
# CycloneDX format (OWASP standard)
docker scout sbom <your-org>/dhi-node:24.11-debian13-fips \
  --format cyclonedx \
  --output node-sbom-cyclonedx.json

Beyond the SBOM, hardened images include 17 different attestations covering SLSA provenance, FIPS compliance, STIG scans, vulnerability scans, and more. We’ll explore how to verify and use these attestations in Part 2 of this blog series.

Trust, But Verify


You’ve now:
✅ Eliminated 100% of vulnerabilities (25 CVEs → 0)
✅ Reduced attack surface by 90% (321 packages → 32)
✅ Shrunk image size by 41.5% (82 MB → 48 MB)
✅ Extracted the SBOM for compliance tracking


The results look good on paper, but verification builds confidence for production. But how do you verify these security claims independently? In Part 2, we’ll explore:

  • Cryptographic signature verification on all attestations
  • Build provenance traced to public GitHub source repositories
  • Deep-dive into FIPS, STIG, and CIS compliance evidence
  • SBOM-driven vulnerability analysis with exploitability context

View related documentation:



目次

関連記事