sha256-<digest>.sig and sha256-<digest>.sbom tags). This is standard Cosign tag-based discovery and is how most signed-image registries operate. However, because Minimus images carry these extra signed artifacts they are sensitive to Hauler’s export method, as explained below.
Prerequisites
- Network access from a “jump” or “transfer” host to
reg.mini.dev(or your Minimus registry endpoint) - If the image is part of a private/subscription set, a valid Minimus pull token for that transfer host to authenticate to the registry (standard Minimus images can be pulled anonymously)
- Hauler v2.0.3 or later installed on that transfer host (
hauler versionto check) - A way to move the resulting Hauler store/bundle into the air-gapped environment (removable media, one-way transfer proxy, etc.)
containerd/ctror registry access on the air-gapped side, depending on which import method you use (see Import into the air-gapped cluster)
Building the manifest and syncing images
Write a Hauler manifest
Create ahauler-manifest.yaml listing the Minimus images you need. For Hauler v2, the manifest must use the v2 API version:
hauler-manifest.yaml
Pin to an immutable reference (recommended)
Minimus rebuilds tags regularly, so note that the tag is mutable. For a reproducible air-gap bundle, pin to either:- Image digest (
reg.mini.dev/postgres@sha256:<digest>) - Minimus timestamp tag (e.g.
reg.mini.dev/postgres:18.6-202608130124) Learn more
Sync the store
--exclude-extras flag tells Hauler to skip pulling the cosign .sig/.sbom artifacts into the store. This flag is required.
Import into the air-gapped cluster
You have two supported paths. Prefer Option A when possible.Option A — hauler store serve registry (recommended, safest even with extras)
1
Move the store
Move the resulting store/bundle to the air-gapped node.
2
Load it
3
Serve it locally
4
Point your container runtime at it
For example, for RKE2, add a
registries.yaml mirror entry targeting the address hauler store serve registry is listening on.sha256-*.sig / .sbom tags rather than colliding with the image tag), so it works even if --exclude-extras was not used during sync.
Option B — ctr images import
1
Move the store
Move the store/bundle to the air-gapped node.
2
Save the OCI layout
3
Import into containerd
--exclude-extras (see Known issue). Without it, the imported tag can silently point at the wrong artifact.
Known issue: images fail with “no command specified”
Symptom: A pod using a Minimus image fails to start with kubelet events such as:Entrypoint/Cmd, even though the same tag has the correct entrypoint in the source registry.
Root cause: This is a Hauler export defect, not a problem with the Minimus image.
When Hauler exports an OCI layout, it labels the Cosign signature and SBOM artifacts with the same io.containerd.image.name annotation as the image itself. ctr images import binds a tag on a “last-entry-wins” basis, so if the SBOM or signature artifact is written last in the index, the local tag ends up pointing at that artifact — which has an empty config ({"config":{}}) — instead of the actual image manifest. As a result, Kubelet has no Entrypoint/Cmd to build a container spec from, and the pod fails every time it’s created.
A related symptom (mismatched image rootfs and manifest layers on ctr images import, without --no-unpack) has the same root cause: the SBOM’s “layer” is an SPDX JSON document, not an actual filesystem layer, so unpacking it fails.
Fix: Use Hauler ≥ v2.0.3 and pass --exclude-extras to hauler store sync. Note that simply upgrading Hauler’s version without adding the flag does not fix the issue.
Alternatively, use the hauler store serve registry workflow described in Option A above, which works correctly without the additional flag.
Non-Hauler alternatives: Tools like crane copy or skopeo copy copy only the image itself, not the attached signature/SBOM artifacts, so they are not affected by this issue.
Verifying the fix
After importing on the air-gapped node, confirm the entrypoint survived the transfer before deploying workloads against it:Entrypoint/Cmd from the source image (e.g. /usr/bin/docker-entrypoint.sh postgres), not an empty array.
Do not remove signatures/SBOMs to work around this
It may be tempting to ask for an unsigned “air-gap tag” without attached artifacts but this is not recommended.--exclude-extras (or crane copy/skopeo copy) already produces exactly that from the existing tag on demand, without requiring Minimus to stop publishing signatures and SBOMs, which would remove supply-chain verification for every other consumer of the image. If you hit this issue, fix the Hauler workflow.
References
- Hauler documentation
- Hauler
--exclude-extrasflag: hauler-dev/hauler#541