Share feedback
Answers are generated based on the documentation.

Use a Docker Hardened Image

You can use a Docker Hardened Image (DHI) just like any other image on Docker Hub. DHIs follow the same familiar usage patterns. Pull them with docker pull, reference them in your Dockerfile, and run containers with docker run.

The key difference is that DHIs are security-focused and intentionally minimal to reduce the attack surface. This means some variants don't include a shell or package manager, and may run as a non-root user by default.

Important

You must authenticate to the Docker Hardened Images registry (dhi.io) to pull DHI Community images. You can authenticate using either of the following:

Run docker login dhi.io to authenticate.

Considerations when adopting DHIs

Docker Hardened Images are intentionally minimal to improve security. If you're updating existing Dockerfiles or frameworks to use DHIs, keep in mind that runtime images don't include shells or package managers, run as non-root users by default, and may have different configurations than images you're familiar with.

For a comprehensive checklist of migration considerations and detailed guidance, see Migrate to Docker Hardened Images.

Pull, run, and reference DHIs

Docker Hardened Images use different image references depending on your subscription:

SubscriptionImage referenceAuthentication
Communitydhi.io/<image>:<tag>docker login dhi.io
Select & Enterprise<your-org>/<image>:<tag>docker login

Select and Enterprise users should mirror repositories to their Docker Hub organization to access compliance variants and customization features.

After authenticating, use the image reference in standard Docker commands and Dockerfiles. For example:

$ docker pull dhi.io/python:3.13
$ docker run --rm dhi.io/python:3.13 python -c "print('Hello from DHI')"
FROM dhi.io/python:3.13
COPY . /app
CMD ["python", "/app/main.py"]

For multi-stage builds:

To learn how to search for available variants, see Search and evaluate images.

Use a DHI in CI/CD pipelines

Docker Hardened Images work just like any other image in your CI/CD pipelines. You can reference them in Dockerfiles, pull them as part of a pipeline step, or run containers based on them during builds and tests.

Unlike typical container images, DHIs also include signed attestations such as SBOMs and provenance metadata. You can incorporate these into your pipeline to support supply chain security, policy checks, or audit requirements if your tooling supports it.

To strengthen your software supply chain, consider adding your own attestations when building images from DHIs. This lets you document how the image was built, verify its integrity, and enable downstream validation and policy enforcement using tools like Docker Scout.

To learn how to attach attestations during the build process, see Docker Build Attestations.

Use a static image for compiled executables

Docker Hardened Images include a static image repository designed specifically for running compiled executables in an extremely minimal and secure runtime. Unlike a non-hardened FROM scratch image, the DHI static image includes attestations and essential packages like ca-certificates.

Use a -dev or other builder image to compile your binary, then copy the output into a static image:

FROM dhi.io/golang:1.22-dev AS build
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o myapp

FROM dhi.io/static:20230311
COPY --from=build /app/myapp /myapp
ENTRYPOINT ["/myapp"]

For more multi-stage build patterns, see the Go migration example.

Use dev variants for framework-based applications

If you're building applications with frameworks that require package managers or build tools (such as Python, Node.js, or Go), use a -dev variant during the development or build stage. These variants include essential utilities like shells, compilers, and package managers to support local iteration and CI workflows.

Use -dev images in your inner development loop or in isolated CI stages to maximize productivity. Once you're ready to produce artifacts for production, switch to a smaller runtime variant to reduce the attack surface and image size.

For detailed multi-stage Dockerfile examples using dev variants, see the migration examples:

Use compliance and ELS variants DHI Select & Enterprise

Subscription: Docker Hardened Images Select or Enterprise

With a DHI Select or DHI Enterprise subscription, you can access additional image variants:

  • Compliance variants: FIPS-enabled and STIG-ready images for regulatory requirements
  • ELS (Extended Lifecycle Support) variants (requires add-on): Security patches for end-of-life image versions

To access these variants, mirror the repository to your Docker Hub organization. For ELS, enable Mirror end-of-life images when setting up mirroring. Once mirrored, use the compliance or EOL tags like any other image tag.

Use with Kubernetes

When deploying Docker Hardened Images to Kubernetes, the process is similar to using any other container image with one key difference: you must configure image pull secrets to authenticate to the DHI registry. This applies whether you're pulling directly from dhi.io, from a mirror on Docker Hub, or from your own third-party registry.

Create an image pull secret

You can create an image pull secret using either an access token or Docker Desktop credentials.

For the --docker-server value:

  • Use dhi.io for community images pulled directly from Docker Hardened Images
  • Use docker.io for mirrored repositories on Docker Hub
  • Use your registry's hostname for third-party registries

Using an access token

Create a secret using a Personal Access Token (PAT) or Organization Access Token (OAT). Ensure the token has at least read-only access to the repositories.

$ kubectl create -n <kubernetes namespace> secret docker-registry <secret name> --docker-server=<registry server> \
        --docker-username=<registry user> --docker-password=<access token> \
        --docker-email=<registry email>

Using Docker Desktop credentials

If you're already authenticated with Docker Desktop, you can create a secret using your stored credentials. This method works for registries you've authenticated to via Docker Desktop (using docker login <registry>).

$ NS=<namespace>
$ kubectl create -n ${NS} secret docker-registry dhi-pull-secret \
    --docker-server=<registry server> \
    --docker-username=<registry user> \
    --docker-password="$(echo https://<registry server> | docker-credential-desktop get | jq -r .Secret)" \
    --docker-email=<registry email>

This method extracts credentials from Docker Desktop's credential store, avoiding the need to create a separate access token for local development.

Test the image pull secret

After creating the secret, verify it works by deploying a test pod that references the secret in its imagePullSecrets configuration.

Create a test pod:

kubectl apply --wait -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: dhi-test
  namespace: <kubernetes namespace>
spec:
  containers:
  - name: test
    image: bash:5
    command: [ "sh", "-c", "echo 'Hello from DHI in Kubernetes!'" ]
  imagePullSecrets:
  - name: <secret name>
EOF

Check the pod status to ensure it completed successfully:

$ kubectl get -n <kubernetes namespace> pods/dhi-test

A successful test shows Completed status:

NAME       READY   STATUS      RESTARTS     AGE
dhi-test   0/1     Completed   ...          ...

If you see ErrImagePull status instead, there's an issue with your secret configuration:

NAME       READY   STATUS         RESTARTS   AGE
dhi-test   0/1     ErrImagePull   0          ...

Verify the pod output matches the expected message:

$ kubectl logs -n <kubernetes namespace> pods/dhi-test
Hello from DHI in Kubernetes!

Clean up the test pod:

$ kubectl delete -n <kubernetes namespace> pods/dhi-test