Images Configuration
Configure automatic image cleanup for Docker runtime images and local registry storage.
Overview
When enabled, Gordon runs a scheduled image prune job that:
- Prunes dangling runtime images that carry positive Gordon provenance.
- Applies tag retention to registry repositories.
- Preserves the
latesttag. - Removes unreferenced blobs after tag cleanup.
- Reports every protected and unknown candidate with its reason.
The CLI gordon images prune runs the same use case and planner as the scheduled job, with the same defaults (keep latest + 3 previous tags, both scopes enabled: dangling runtime images and registry tag retention). App state existing on the server is normal and never disables pruning; the plan decides per candidate.
Configuration
[images]
# Docker Hub, ghcr.io, quay.io, and Gordon's registry are already allowed.
allowed_registries = ["registry.internal:5000"]
require_digest = false
[images.prune]
enabled = false
schedule = "daily"
keep_last = 3
Settings
| Key | Type | Default | Description |
|---|---|---|---|
images.allowed_registries |
array | [] |
Additional registry hostname+port entries. Docker Hub (docker.io, canonical pull host registry-1.docker.io), ghcr.io, quay.io, and Gordon's configured registry are always allowed. Include non-default ports, e.g. "registry.example.com:5000". Hostnames are case-insensitive; one trailing dot and port 443 are canonicalized. This setting does not configure registry credentials. |
images.require_digest |
bool | false |
Require every image reference, including Gordon registry images, to use a valid @sha256:<64 hex chars> digest. |
images.prune.enabled |
bool | false |
Enables scheduled image cleanup |
images.prune.schedule |
string | "daily" |
Schedule preset: hourly, daily, weekly, monthly |
images.prune.keep_last |
int | 3 |
Number of newest non-latest tags kept per repository during registry cleanup (latest is always kept when present) |
The policy validates registry names and strict SHA-256 digest syntax at manifest apply, digest resolution, deployment preflight, and immediately before each pull. It rejects malformed, userinfo-bearing, and ambiguous authorities. External app images currently require digest-pinned references, independently of require_digest; external tag resolution is not available. External pulls are anonymous, so adding a host to allowed_registries does not enable authenticated private-registry access. This hostname allowlist does not prove that DNS resolves to a public address and does not constrain runtime egress; enforce destination-level restrictions in the host firewall or runtime network policy.
Retention Behavior
latestis always preserved.keep_lastapplies per repository and counts non-latesttags.keep_lastsets a minimum retained set, not a maximum: a tag named by durable app state, or referenced by the OCI closure of a protected manifest, survives beyond the window.keep_last = 0skips registry tag/blob cleanup entirely (runtime dangling prune still runs).- Negative
keep_lastvalues are invalid.
Prune Safety
A prune deletes only resources it can positively prove safe. Each candidate gets one verdict: eligible (deleted), protected (a durable fact claims it), or unknown (a required fact could not be read). Protected and unknown candidates are reported and left in place; an operation that deletes nothing is a success.
Durable protection covers the DESIRED and ACTIVE state of every app, including stopped and partially converged services; recovery inhibitions; staged and committed apply intents; unfinished operation journal entries; runtime container use for running and stopped containers; recent uploads; and the transitive OCI closure of every retained manifest. Durable digest roots are repository-qualified, so moving a tag away from a deployed image keeps that manifest's config, layers, child manifests, and subject content protected. An unreadable, unsupported, or unresolvable manifest makes the blobs whose safety depended on it unknown instead of eligible.
Registry content is repository-scoped: a blob is served only to a repository that completed an upload of that digest, and a manifest may only reference config, layers, and child manifests that repository owns. Image labels never authorize deletion of a runtime image; eligibility requires a matching released ownership claim from the app that pinned it, no container use, and a complete inventory.
An exclusive GC lease serializes prune against app apply, deploy, start, restart, remove, recovery, and restore. Those paths hold a shared lease from validation/resource acquisition through the durable publication of that resource's protection, and an apply verifies the expected desired revision so a stale apply cannot overwrite a newer one.