Docker just made its entire catalog of more than 1,000 Docker Hardened Images (DHI) free and fully open source under the Apache 2.0 license. If you’re self-hosting anything in containers — from databases to AI pipelines to home automation — this is probably the single biggest security upgrade you can make today with zero code changes.

Here’s what changed, why it matters, and how to migrate your stack in an afternoon.

What Are Docker Hardened Images?

Docker Hardened Images are minimal, security-focused container base images maintained directly by Docker. Launched in May 2025 as a paid enterprise product, they were open-sourced in December 2025 and are now available to everyone.

Compared to the community images most of us pull from Docker Hub, DHIs are fundamentally different:

  • Rootless by default — every image runs as a non-root user out of the box
  • Minimal attack surface — stripped of unnecessary packages, shells, and debugging tools in the runtime variant
  • Up to 95% fewer CVEs — Docker claims hardened images reduce inherited vulnerabilities by up to 95% compared to traditional community images
  • Cryptographically signed — every image ships with SBOM (Software Bill of Materials) and VEX (Vulnerability Exploitability eXchange) metadata
  • Built from source — Docker builds, patches, and maintains all system packages directly from upstream source code

Think of it as the difference between running a stock Ubuntu desktop install as your server OS versus a minimal, hardened Debian netinstall. Same software underneath, dramatically smaller target for attackers.

The Three Tiers

Docker now offers DHI in three tiers:

Tier Cost What You Get
Community (Free) /bin/bash 1,000+ hardened images, Apache 2.0 license, SBOM/VEX metadata, rootless defaults
Enterprise Paid Continuous updates, 7-day SLA on CVE patches, custom image builder, compliance tooling
Extended Lifecycle Paid Security patches after upstream EOL — critical for regulated industries

For self-hosters, the free Community tier is the sweet spot. You get the same hardened base images that enterprise customers use, with full access to the source code on GitHub.

Why Self-Hosters Should Care

If you’re running self-hosted services on a Cloud VPS, your containers almost certainly use community base images that carry dozens (sometimes hundreds) of inherited CVEs. Most of these vulnerabilities exist in packages your application never actually uses — but they still show up in security scans and expand your attack surface.

Here’s a real-world example. Run docker scout cves against a standard node:20 image and you’ll typically see 200+ vulnerabilities. The equivalent Docker Hardened Image? Often fewer than 10, sometimes zero.

This matters for three reasons:

  1. Smaller blast radius — fewer packages means fewer things that can be exploited if an attacker gets inside your container
  2. Cleaner compliance — if you’re working toward SOC 2, ISO 27001, or even just want to pass a client security questionnaire, zero-CVE base images are a massive win
  3. Less maintenance — fewer inherited CVEs means fewer emergency patch cycles when scanners flag your images

If you are already security-conscious about your container stack, you may also want to look at running tini as your Docker init system — it pairs well with hardened images by ensuring your PID 1 handles signals correctly without a full shell.

How to Migrate: The Drop-In Swap

The migration is surprisingly simple for most self-hosted stacks. Docker designed DHIs as drop-in replacements for their Official Image counterparts.

Step 1: Find Your Hardened Replacement

Browse the DHI catalog on Docker Hub. Common self-hosted images already available include:

  • docker.io/dockerhardened/python — replaces python
  • docker.io/dockerhardened/node — replaces node
  • docker.io/dockerhardened/postgres — replaces postgres
  • docker.io/dockerhardened/nginx — replaces nginx
  • docker.io/dockerhardened/redis — replaces redis
  • docker.io/dockerhardened/golang — replaces golang

CNCF projects like Prometheus, Grafana, and CoreDNS also have dedicated hardened images maintained through Docker’s CNCF partnership.

Step 2: Update Your Dockerfile

For a typical multi-stage build, the change is often a single line:

# Before
FROM node:20-alpine AS build
RUN npm ci && npm run build

FROM node:20-alpine
COPY --from=build /app/dist /app
CMD ["node", "/app/index.js"]

# After — Docker Hardened Image
FROM docker.io/dockerhardened/node:20-alpine-dev AS build
RUN npm ci && npm run build

FROM docker.io/dockerhardened/node:20-alpine
COPY --from=build /app/dist /app
CMD ["node", "/app/index.js"]

Key detail: DHI images come in two variants:

  • dev / sdk — includes build tools (compilers, package managers). Use this in your build stage.
  • Runtime (default) — stripped to the minimum. No shell, no debugging tools. Use this for your final image.

Step 3: Use Gordon for Automatic Migration

Docker’s AI assistant, Gordon, can automatically analyze your Dockerfile and suggest the hardened replacement. If you have Docker Desktop installed:

docker ai "migrate my Dockerfile to use Docker Hardened Images"

Gordon will identify your base image, find the DHI equivalent, and generate the updated Dockerfile with the correct variant tags.

Step 4: Handle Missing Packages

Since DHIs are minimal, your application might need packages that aren’t included. Add them explicitly in your Dockerfile:

FROM docker.io/dockerhardened/python:3.12-alpine-dev AS build
# Install build dependencies
RUN apk add --no-cache gcc musl-dev libffi-dev
RUN pip install --no-cache-dir -r requirements.txt

FROM docker.io/dockerhardened/python:3.12-alpine
COPY --from=build /usr/local/lib/python3.12 /usr/local/lib/python3.12
COPY . /app
CMD ["python", "/app/main.py"]

Step 5: Handle the No-Shell Runtime

DHI runtime images don’t include a shell. This means docker exec -it container /bin/sh won’t work. Instead, use Docker Debug:

docker debug mycontainer

This attaches a debugging sidecar without modifying the running container — actually more secure than shelling in directly.

Docker Compose Migration for Existing Stacks

For self-hosted stacks using Docker Compose, you can migrate service by service. Here’s an example with a typical monitoring stack:

services:
  # Before: community images
  # postgres:
  #   image: postgres:16-alpine

  # After: hardened
  postgres:
    image: docker.io/dockerhardened/postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

  redis:
    image: docker.io/dockerhardened/redis:7-alpine
    volumes:
      - redisdata:/data

Important: since DHI images are rootless, check that your volume permissions are compatible. If your existing data directory is owned by root, you may need to chown it to the non-root UID used by the hardened image (typically 65532 or a service-specific UID).

Verifying Your Migration

After swapping images, verify the security improvement:

# Scan the old image
docker scout cves postgres:16-alpine

# Scan the hardened replacement
docker scout cves docker.io/dockerhardened/postgres:16-alpine

# Check SBOM metadata
docker sbom docker.io/dockerhardened/postgres:16-alpine

# Verify the image signature
docker trust inspect docker.io/dockerhardened/postgres:16-alpine

You should see a dramatic reduction in CVE count. The SBOM gives you a complete inventory of every package in the image — useful for compliance audits and incident response.

What This Means for Your Self-Hosted Stack

Docker Hardened Images aren’t just a security feature — they’re a shift in how container security works at the base layer. Instead of inheriting hundreds of CVEs from upstream and hoping scanners catch the real risks, you start from a clean, minimal, auditable foundation.

Combined with recent security improvements like Docker v29’s containerd default and nftables migration, the self-hosted container security story in 2026 is dramatically better than even a year ago.

If you’re running containers on a CWH Cloud VPS, start by swapping one non-critical service (Redis is a good first candidate — minimal config, easy to roll back). Verify it works, check the CVE reduction, then work through the rest of your stack.

For production workloads where you need guaranteed patch SLAs or compliance documentation, CWH Managed Support can help you plan and execute the migration across your entire infrastructure.

Quick Reference

Resource Link
DHI Catalog Docker Hub
Migration Guide docs.docker.com/dhi/migration
Source Code GitHub
Gordon AI Migration docs.docker.com/dhi/get-started
Docker Debug docs.docker.com/reference/cli/docker/debug