dhictl is a command-line interface (CLI) tool for managing Docker Hardened Images (DHI) — minimal, secure, and production-ready container base and application images maintained by Docker.
dhictl lets you:
- Browse the catalog of available DHI images and their metadata
- Mirror DHI images to your Docker Hub organization
- Create and manage customizations of DHI images (including bulk operations)
- Monitor customization builds
- Inspect attestations attached to DHI images (SLSA provenance, SBOMs)
dhictl will be available by default on Docker Desktop soon.
In the meantime, you can also install dhictl manually as a Docker CLI plugin or as a standalone binary.
- Download the
dhictlbinary for your platform from the releases page. - Rename the binary:
docker-dhion Linux and macOSdocker-dhi.exeon Windows
- Copy it to the CLI plugins directory:
$HOME/.docker/cli-pluginson Linux and macOS%USERPROFILE%\.docker\cli-pluginson Windows
- Make it executable on Linux and macOS:
chmod +x $HOME/.docker/cli-plugins/docker-dhi
- Run
docker dhito verify the installation.
- Download the
dhictlbinary for your platform from the releases page. - Move it to a directory in your
PATH:mv dhictl /usr/local/bin/on Linux and macOS- Move
dhictl.exeto a directory in yourPATHon Windows
Note: The following examples use
dhictlto reference the CLI tool. Depending on your installation, you may need to replacedhictlwithdocker dhi.
Every command has built-in help accessible with the --help flag:
dhictl --help
dhictl catalog list --helpThe dhictl comes with completion so you can get suggestions for commands, flags, and arguments as you type.
To enable completion for your current terminal session, run:
source <(dhictl completion bash) # for bash
source <(dhictl completion zsh) # for zsh
source <(dhictl completion fish) # for fish
source <(dhictl completion powershell) # for powershellYou can also dump the output of the dhictl completion command to a file and source it from your shell configuration
file for persistent completion.
Use dhictl completion --help for more details.
List all available DHI images:
dhictl catalog listFilter by type, name, or compliance:
dhictl catalog list --type image
dhictl catalog list --filter golang
dhictl catalog list --fipsGet details of a specific image, including available tags and CVE counts:
dhictl catalog get <image-name>Start mirroring one or more DHI images to your Docker Hub organization:
dhictl mirror start --org my-org \
-r dhi/golang,my-org/dhi-golang \
-r dhi/nginx,my-org/dhi-nginx \
-r dhi/prometheus-chart,my-org/dhi-prometheus-chartList mirrored images in your organization:
dhictl mirror list --org my-orgStop mirroring an image:
dhictl mirror stop --org my-org dhi-golangGenerate a customization YAML file from a DHI base image tag:
dhictl customization prepare --org my-org golang 1.25 \
--destination my-org/dhi-golang \
--name "golang with git" \
> my-customization.yamlThe YAML customization syntax documentation is coming soon.
Edit the generated YAML file to add packages, environment variables, or other changes, then create the customization:
dhictl customization create --org my-org my-customization.yamlTo prepare customizations for multiple targets at once, pipe a JSON array of {destination, tag-definition-id} objects via stdin:
echo '[
{"destination": "my-org/dhi-golang", "tag-definition-id": "golang/alpine-3.23/1.26"},
{"destination": "my-org/dhi-golang", "tag-definition-id": "golang/alpine-3.23/1.26-dev"},
{"destination": "my-org/dhi-python", "tag-definition-id": "python/alpine-3.23/3.14-dev"},
{"destination": "my-org/dhi-python", "tag-definition-id": "python/alpine-3.23/3.14"}
]' | dhictl customization prepare --name "cross repo customization" > my-bulk-customization.yamlThe generated YAML will have a targets list instead of a single target. Note that some options (like accounts and entrypoint) are not available in bulk mode since they may not apply uniformly across all targets.
Edit the YAML and create all customizations in one go:
dhictl customization create --org my-org my-bulk-customization.yamlTo apply the same customization to additional targets, retrieve the existing YAML and add entries to the targets list:
dhictl customization get --org my-org <customization-id> > my-customization.yamlThe YAML will have a single target:
targets:
- destination: my-org/dhi-golang
tag_definition_id: golang/debian-13/1.26Add more targets to turn it into a bulk customization:
targets:
- destination: my-org/dhi-golang
tag_definition_id: golang/debian-13/1.26
- destination: my-org/dhi-golang
tag_definition_id: golang/alpine-3.23/1.26
- destination: my-org/dhi-golang
tag_definition_id: golang/alpine-3.23/1.26-devNote: applying the same customization across distributions is only possible if all referenced packages exist in every distribution with the same name, otherwise the build will fail.
Then create the new customizations from the updated YAML:
dhictl customization create --org my-org my-customization.yamlTo narrow a bulk customization back to a single target, retrieve the YAML and reduce the targets list to one entry:
dhictl customization get --org my-org <customization-id> --output my-customization.yamlEdit the YAML to keep only one target, then you can also uncomment the accounts and entrypoint sections that are unavailable in bulk mode:
targets:
- destination: my-org/dhi-golang
tag_definition_id: golang/debian-13/1.26
accounts:
runs-as: nonroot
users:
- name: nonroot
uid: 65532
groups:
- name: nonroot
gid: 65532Create a new customization from the updated YAML:
dhictl customization create --org my-org my-customization.yamldhictl customization list --org my-orgRetrieve the existing customization and dump it into a yaml file:
dhictl customization get --org my-org <customization-id> --output my-customization.yamlThen, create a new customization using the same YAML file, but with a tag-definition-id:
dhictl customization create --org my-org --tag-definition-id golang/debian-13/1.25 my-customization.yaml
dhictl customization create --org my-org --tag-definition-id golang/debian-13/1.26 my-customization.yaml
dhictl customization create --org my-org --tag-definition-id golang/alpine-3.23/1.25 my-customization.yaml
dhictl customization create --org my-org --tag-definition-id golang/alpine-3.23/1.26 my-customization.yamlNote: this is an example where we apply the same customization to different distribution. This is only possible if the list of packages contains packages that are available in both distributions with the same exact name otherwise the build will fail.
You can even do that cross-repository:
dhictl customization create --org my-org --tag-definition-id golang/debian-13/1.25 --destination my-org/dhi-other-golang my-customization.yamlRetrieve the current customization YAML:
dhictl customization get --org my-org <customization-id> --output my-customization.yamlEdit the YAML file, then apply the update:
dhictl customization edit --org my-org my-customization.yamldhictl customization delete --org my-org <customization-id>List builds for a customization:
dhictl customization build list --org my-org <customization-id>Get details of a specific build:
dhictl customization build get --org my-org <customization-id> <build-id>View build logs:
dhictl customization build logs --org my-org <customization-id> <build-id>DHI images ship with attestations (SLSA provenance, SBOMs, etc.) attached as OCI referrers. Use the attestation commands to list and retrieve them.
dhictl attestation list dhi.io/nginx:1.27Filter by platform or predicate type:
# Filter by platform
dhictl attestation list dhi.io/nginx:1.27 --platform linux/amd64
# Filter by predicate type
dhictl attestation list dhi.io/nginx:1.27 --predicate-type https://spdx.dev/Document
# Filter by multiple predicate types
dhictl attestation list dhi.io/nginx:1.27 \
--predicate-type https://spdx.dev/Document \
--predicate-type https://slsa.dev/provenance/v1First list the available attestations to find the referrer digest, then retrieve the full in-toto statement:
dhictl attestation get dhi.io/nginx:1.27 sha256:<digest>Save the attestation to a file or extract the predicate with jq:
# Save to file
dhictl attestation get dhi.io/nginx:1.27 sha256:<digest> --output provenance.json
# Extract the predicate
dhictl attestation get dhi.io/nginx:1.27 sha256:<digest> | jq .predicateDisplay a human-readable summary of the SPDX SBOM attached to an image:
dhictl attestation sbom dhi.io/nginx:1.27
# For a specific platform
dhictl attestation sbom dhi.io/nginx:1.27 --platform linux/amd64Most list and get commands support a --json flag for machine-readable output:
dhictl catalog list --json
dhictl mirror list --org my-org --json
dhictl customization list --org my-org --json
dhictl attestation list dhi.io/nginx:1.27 --jsondhictl can be configured with a YAML file located at:
$HOME/.config/dhictl/config.yamlon Linux and macOS%USERPROFILE%\.config\dhictl\config.yamlon Windows
If $XDG_CONFIG_HOME is set, the configuration file is located at $XDG_CONFIG_HOME/dhictl/config.yaml (see the XDG Base Directory Specification).
Available configuration options:
| Option | Environment Variable | Description |
|---|---|---|
org |
DHI_ORG |
Default Docker Hub organization for mirror and customization commands. |
api_token |
DHI_API_TOKEN |
Docker token for authentication. You can generate a token in your Docker Hub account settings. |
disable_update_notifier |
DHI_NO_UPDATE_NOTIFIER or CLI |
Disable the update notice printed on stderr. |
Environment variables take precedence over configuration file values.
dhictl is licensed under the Terms and Conditions of the Docker Subscription Service Agreement.
- Docker Hardened Images: docker.com/products/hardened-images
- Issue Tracker: GitHub Issues
- Discussions: GitHub Discussions
Docker Hardened Images - Building secure containers, together.