v3.1.0 d676137

images.md RawHistoryFolder

Images Command

Push, list, and prune runtime/registry images.

gordon images

gordon images <subcommand>

Subcommands:

  • push - Tag and push an image to the Gordon registry (never deploys).
  • list - List runtime images and registry tags.
  • prune - Prune dangling runtime images and old registry tags.
  • tags - List registry tags for a specific repository.

Note: Images commands require remote mode (--remote + --token, or configured remotes).

gordon images push

Tag and push an image to the Gordon registry. Push transfers OCI content only: it never deploys. Deploy separately with gordon apps deploy after applying the manifest that references the pushed tag.

Synopsis

gordon images push [image] [options]

Arguments

Argument Description
[image] Image name to push (optional). If omitted, auto-detected from Dockerfile labels or current directory name

Options

Option Description
--build Build the image first using docker buildx
-f, --file Path to Dockerfile (default: ./Dockerfile, used with --build)
--platform Target platform for buildx (default: linux/amd64)
--build-arg Additional build args (repeatable, KEY=VALUE)
--tag Override pushed version tag (default: tag ref from CI, then git describe --tags --dirty)
--remote, -r Remote name or URL (e.g., prod, https://gordon.mydomain.com)
--token Authentication token for remote

Description

gordon images push tags the selected image for the Gordon registry and pushes it.

If you do not pass --remote and no active remote is configured, Gordon tries to infer the correct saved remote by probing your saved remotes for the image. It auto-selects only when exactly one remote matches. If multiple remotes match, or a saved remote cannot be probed safely, the command stops and asks you to use --remote explicitly.

Domain-style push targets are retired: push an image name, then gordon apps apply the manifest that references the pushed tag.

  • The version tag defaults to a CI tag ref (like refs/tags/v1.2.3) when available, then falls back to git describe --tags --dirty (for example v1.2.3-4-gabc1234 or v1.2.3-dirty). If no tag is found, latest is used.
  • When --build is set, the command builds with docker buildx build --load and injects VERSION, GIT_TAG, GIT_SHA, and BUILD_TIME into the build environment plus any --build-arg values. To use these in your Dockerfile, declare them with ARG (e.g., ARG VERSION) then reference via ENV or in build steps.
  • Use -f/--file to build from a Dockerfile outside the current directory root.
  • The version tag and latest are both pushed (unless the version is latest).

Authentication

When used with --remote, gordon images push authenticates in two ways:

  • Admin API (tag listing for inference): uses --token or $GORDON_TOKEN as Bearer token
  • Registry push: automatically exchanges the token for a short-lived (5 min) registry access token via /auth/token -- no docker login required

This means CI/CD pipelines only need a single secret (GORDON_TOKEN).

Version Auto-Detection

Gordon reads version tags from CI environment variables (in priority order):

CI System Variable Example
GitHub Actions $GITHUB_REF refs/tags/v1.2.0
GitHub Actions $GITHUB_REF_TYPE + $GITHUB_REF_NAME tag + v1.2.0
GitLab CI $CI_COMMIT_TAG v1.2.0
Azure DevOps $BUILD_SOURCEBRANCH refs/tags/v1.2.0
Any git describe --tags v1.2.3-4-gabc1234
Fallback - latest

Examples

# Build, push (auto-detect image name)
gordon images push --build --remote https://gordon.example.com

# Push an image
gordon images push myapp --remote https://gordon.example.com

# Push a fully qualified ref
gordon images push registry.example.com/myapp:v1.2.3 --build --remote https://gordon.example.com

# Push existing local image with an explicit tag
gordon images push myapp --tag v1.2.0 --remote https://gordon.example.com

# Build for ARM and pass build args
gordon images push myapp --build --platform linux/arm64 --build-arg CGO_ENABLED=0 --remote https://gordon.example.com

# Build from a custom Dockerfile path
gordon images push myapp --build -f docker/app/Dockerfile --remote https://gordon.example.com

# CI/CD usage (single env var, no docker login needed)
export GORDON_TOKEN="your-token"
gordon images push myapp --build --remote https://gordon.example.com

Notes

  • Remote mode required. See CLI Overview for targeting options.
  • --build requires Docker with Buildx. Docker Desktop includes it; on Linux, install the docker-buildx-plugin package.
  • Gordon uses native registry uploads instead of shelling out to docker push. Image layers are sent in 50MB chunks, which stays under Cloudflare's 100MB per-request limit so proxied pushes keep working. Keep the server's max_blob_chunk_size larger than the client chunk size; the default 95MB works out of the box.

gordon images list

gordon images list
gordon images list --json

Shows image rows with repository, tag, size, creation time, image id, and dangling status. Rows that exist only in the registry (not currently present in the runtime cache) are included with unavailable runtime fields shown as -.

Flags:

Flag Description
--json Output images as JSON

JSON Output

gordon images list --json
[
  {
    "repository": "myapp",
    "tag": "latest",
    "size": "148MB",
    "created_at": "2026-03-13T10:15:00Z",
    "image_id": "sha256:abc123def456",
    "dangling": false
  }
]

gordon images prune

gordon images prune [--dry-run] [--keep-releases <n>] [--dangling] [--registry] [--no-confirm]

By default, prune removes dangling runtime images and applies registry tag retention (keeping latest + 3 previous non-latest tags per repository). A confirmation prompt is shown before destructive operations.

A prune only ever deletes resources it can positively prove safe. Every other candidate is reported as protected or unknown and left in place; the command still succeeds. See Prune safety.

Flags:

Flag Default Description
--dry-run false Run the full inventory and planning, then report; nothing is deleted
--keep-releases 3 Number of previous non-latest tags to keep per repository (latest is always preserved)
--dangling false Restrict scope to dangling runtime images only
--registry false Restrict scope to registry tag retention only
--no-confirm false Skip the confirmation prompt

Scope resolution

  • No scope flags (default): both runtime and registry cleanup run.
  • --dangling: only runtime dangling images are pruned; registry is skipped.
  • --registry: only registry tag retention runs; runtime is skipped.
  • --dangling --registry: both scopes run (same as default, but explicit).

Retention semantics

  • latest is always preserved when present.
  • --keep-releases counts non-latest tags, ordered by most recent first.
  • A tag named by durable app state survives beyond the retention window.
  • --keep-releases=0 skips registry tag and blob cleanup entirely; dangling runtime prune still runs.

Prune safety

Gordon prunes by ownership, not by name or age. Each candidate gets one verdict:

Verdict Meaning
eligible Every fact needed to prove the resource safe was read completely, and no durable record claims it. It is deleted.
protected A durable fact claims it: a desired or active app service (including stopped apps), a recovery inhibition, a staged or committed apply intent, an unfinished operation journal entry, container use, a pending upload, an ownership record, or the OCI closure of any of those. It survives.
unknown A fact needed to prove it safe was missing, unreadable, or unsupported. It survives.

Runtime images used by any container, running or stopped, always survive. Registry blobs reachable from a retained or protected manifest survive, including blobs shared with another tag. When a retained manifest cannot be read, the blobs whose safety depended on it become unknown rather than eligible.

Both --dry-run and the executed prune return the same report: the verdict counts, the deleted identities, any deletion failures, every inventory gap, and the skipped candidates with their reason codes. A prune that deletes nothing is a success.

gordon images tags

gordon images tags <repository>
gordon images tags <repository> --json

Lists all tags in the Gordon registry for the specified repository.

Flags:

Flag Description
--json Output repository and tags as JSON

JSON Output

gordon images tags myapp --json
{
  "repository": "myapp",
  "tags": ["latest", "v1.2.0", "v1.1.0"]
}

Examples

# List images
gordon images list

# Prune everything with defaults (dangling + registry, keep latest + 3)
gordon images prune

# List tags for a repository
gordon images tags myapp

# Prune dangling runtime images only
gordon images prune --dangling

# Prune registry tags only, keeping latest + 5 previous
gordon images prune --registry --keep-releases 5

# Inspect what prune would remove without applying
# (also lists every skipped candidate with its reason)
gordon images prune --dry-run

# Skip confirmation prompt
gordon images prune --no-confirm

Required Permissions

  • The list subcommand requires admin:status:read.
  • The prune subcommand requires admin:config:write.
  • The tags subcommand requires admin:status:read.
source
1# Images Command
2
3Push, list, and prune runtime/registry images.
4
5## gordon images
6
7```bash
8gordon images <subcommand>
9```
10
11Subcommands:
12
13- `push` - Tag and push an image to the Gordon registry (never deploys).
14- `list` - List runtime images and registry tags.
15- `prune` - Prune dangling runtime images and old registry tags.
16- `tags` - List registry tags for a specific repository.
17
18> **Note:** Images commands require remote mode (`--remote` + `--token`, or configured remotes).
19
20## gordon images push
21
22Tag and push an image to the Gordon registry. Push transfers OCI content
23only: it never deploys. Deploy separately with `gordon apps deploy` after
24applying the manifest that references the pushed tag.
25
26### Synopsis
27
28```bash
29gordon images push [image] [options]
30```
31
32### Arguments
33
34| Argument | Description |
35|----------|-------------|
36| `[image]` | Image name to push (optional). If omitted, auto-detected from Dockerfile labels or current directory name |
37
38### Options
39
40| Option | Description |
41|--------|-------------|
42| `--build` | Build the image first using `docker buildx` |
43| `-f, --file` | Path to Dockerfile (default: `./Dockerfile`, used with `--build`) |
44| `--platform` | Target platform for buildx (default: `linux/amd64`) |
45| `--build-arg` | Additional build args (repeatable, `KEY=VALUE`) |
46| `--tag` | Override pushed version tag (default: tag ref from CI, then `git describe --tags --dirty`) |
47| `--remote, -r` | Remote name or URL (e.g., prod, https://gordon.mydomain.com) |
48| `--token` | Authentication token for remote |
49
50### Description
51
52`gordon images push` tags the selected image for the Gordon registry and pushes it.
53
54If you do not pass `--remote` and no active remote is configured, Gordon tries to
55infer the correct saved remote by probing your saved remotes for the image.
56It auto-selects only when exactly one remote matches. If multiple remotes match,
57or a saved remote cannot be probed safely, the command stops and asks you to use
58`--remote` explicitly.
59
60Domain-style push targets are retired: push an image name, then
61`gordon apps apply` the manifest that references the pushed tag.
62
63- The version tag defaults to a CI tag ref (like `refs/tags/v1.2.3`) when available,
64  then falls back to `git describe --tags --dirty` (for example
65  `v1.2.3-4-gabc1234` or `v1.2.3-dirty`). If no tag is found, `latest` is used.
66- When `--build` is set, the command builds with `docker buildx build --load`
67  and injects `VERSION`, `GIT_TAG`, `GIT_SHA`, and `BUILD_TIME` into the build
68  environment plus any `--build-arg` values. To use these in your Dockerfile,
69  declare them with `ARG` (e.g., `ARG VERSION`) then reference via `ENV` or
70  in build steps.
71- Use `-f/--file` to build from a Dockerfile outside the current directory root.
72- The version tag and `latest` are both pushed (unless the version is `latest`).
73
74### Authentication
75
76When used with `--remote`, gordon images push authenticates in two ways:
77
78- **Admin API** (tag listing for inference): uses `--token` or `$GORDON_TOKEN` as Bearer token
79- **Registry push**: automatically exchanges the token for a short-lived (5 min) registry access token via `/auth/token` -- no `docker login` required
80
81This means CI/CD pipelines only need a single secret (`GORDON_TOKEN`).
82
83### Version Auto-Detection
84
85Gordon reads version tags from CI environment variables (in priority order):
86
87| CI System | Variable | Example |
88|-----------|----------|---------|
89| GitHub Actions | `$GITHUB_REF` | `refs/tags/v1.2.0` |
90| GitHub Actions | `$GITHUB_REF_TYPE` + `$GITHUB_REF_NAME` | `tag` + `v1.2.0` |
91| GitLab CI | `$CI_COMMIT_TAG` | `v1.2.0` |
92| Azure DevOps | `$BUILD_SOURCEBRANCH` | `refs/tags/v1.2.0` |
93| Any | `git describe --tags` | `v1.2.3-4-gabc1234` |
94| Fallback | - | `latest` |
95
96### Examples
97
98```bash
99# Build, push (auto-detect image name)
100gordon images push --build --remote https://gordon.example.com
101
102# Push an image
103gordon images push myapp --remote https://gordon.example.com
104
105# Push a fully qualified ref
106gordon images push registry.example.com/myapp:v1.2.3 --build --remote https://gordon.example.com
107
108# Push existing local image with an explicit tag
109gordon images push myapp --tag v1.2.0 --remote https://gordon.example.com
110
111# Build for ARM and pass build args
112gordon images push myapp --build --platform linux/arm64 --build-arg CGO_ENABLED=0 --remote https://gordon.example.com
113
114# Build from a custom Dockerfile path
115gordon images push myapp --build -f docker/app/Dockerfile --remote https://gordon.example.com
116
117# CI/CD usage (single env var, no docker login needed)
118export GORDON_TOKEN="your-token"
119gordon images push myapp --build --remote https://gordon.example.com
120```
121
122### Notes
123
124- Remote mode required. See [CLI Overview](./index.md) for targeting options.
125- `--build` requires Docker with Buildx. Docker Desktop includes it; on Linux,
126  install the `docker-buildx-plugin` package.
127- Gordon uses native registry uploads instead of shelling out to `docker push`.
128  Image layers are sent in 50MB chunks, which stays under Cloudflare's 100MB
129  per-request limit so proxied pushes keep working. Keep the server's
130  `max_blob_chunk_size` larger than the client chunk size; the default `95MB`
131  works out of the box.
132
133## gordon images list
134
135```bash
136gordon images list
137gordon images list --json
138```
139
140Shows image rows with repository, tag, size, creation time, image id, and dangling status.
141Rows that exist only in the registry (not currently present in the runtime cache) are included with unavailable runtime fields shown as `-`.
142
143Flags:
144
145| Flag | Description |
146|------|-------------|
147| `--json` | Output images as JSON |
148
149### JSON Output
150
151```bash
152gordon images list --json
153```
154
155```json
156[
157  {
158    "repository": "myapp",
159    "tag": "latest",
160    "size": "148MB",
161    "created_at": "2026-03-13T10:15:00Z",
162    "image_id": "sha256:abc123def456",
163    "dangling": false
164  }
165]
166```
167
168## gordon images prune
169
170```bash
171gordon images prune [--dry-run] [--keep-releases <n>] [--dangling] [--registry] [--no-confirm]
172```
173
174By default, prune removes dangling runtime images **and** applies registry tag retention (keeping `latest` + 3 previous non-`latest` tags per repository). A confirmation prompt is shown before destructive operations.
175
176A prune only ever deletes resources it can positively prove safe. Every other candidate is reported as `protected` or `unknown` and left in place; the command still succeeds. See [Prune safety](#prune-safety).
177
178Flags:
179
180| Flag | Default | Description |
181|------|---------|-------------|
182| `--dry-run` | `false` | Run the full inventory and planning, then report; nothing is deleted |
183| `--keep-releases` | `3` | Number of previous non-`latest` tags to keep per repository (`latest` is always preserved) |
184| `--dangling` | `false` | Restrict scope to dangling runtime images only |
185| `--registry` | `false` | Restrict scope to registry tag retention only |
186| `--no-confirm` | `false` | Skip the confirmation prompt |
187
188### Scope resolution
189
190- **No scope flags** (default): both runtime and registry cleanup run.
191- **`--dangling`**: only runtime dangling images are pruned; registry is skipped.
192- **`--registry`**: only registry tag retention runs; runtime is skipped.
193- **`--dangling --registry`**: both scopes run (same as default, but explicit).
194
195### Retention semantics
196
197- `latest` is always preserved when present.
198- `--keep-releases` counts non-`latest` tags, ordered by most recent first.
199- A tag named by durable app state survives beyond the retention window.
200- `--keep-releases=0` skips registry tag and blob cleanup entirely; dangling runtime prune still runs.
201
202## Prune safety
203
204Gordon prunes by ownership, not by name or age. Each candidate gets one verdict:
205
206| Verdict | Meaning |
207|---------|---------|
208| `eligible` | Every fact needed to prove the resource safe was read completely, and no durable record claims it. It is deleted. |
209| `protected` | A durable fact claims it: a desired or active app service (including stopped apps), a recovery inhibition, a staged or committed apply intent, an unfinished operation journal entry, container use, a pending upload, an ownership record, or the OCI closure of any of those. It survives. |
210| `unknown` | A fact needed to prove it safe was missing, unreadable, or unsupported. It survives. |
211
212Runtime images used by any container, running or stopped, always survive. Registry blobs reachable from a retained or protected manifest survive, including blobs shared with another tag. When a retained manifest cannot be read, the blobs whose safety depended on it become `unknown` rather than eligible.
213
214Both `--dry-run` and the executed prune return the same report: the verdict counts, the deleted identities, any deletion failures, every inventory gap, and the skipped candidates with their reason codes. A prune that deletes nothing is a success.
215
216## gordon images tags
217
218```bash
219gordon images tags <repository>
220gordon images tags <repository> --json
221```
222
223Lists all tags in the Gordon registry for the specified repository.
224
225Flags:
226
227| Flag | Description |
228|------|-------------|
229| `--json` | Output repository and tags as JSON |
230
231### JSON Output
232
233```bash
234gordon images tags myapp --json
235```
236
237```json
238{
239  "repository": "myapp",
240  "tags": ["latest", "v1.2.0", "v1.1.0"]
241}
242```
243
244## Examples
245
246```bash
247# List images
248gordon images list
249
250# Prune everything with defaults (dangling + registry, keep latest + 3)
251gordon images prune
252
253# List tags for a repository
254gordon images tags myapp
255
256# Prune dangling runtime images only
257gordon images prune --dangling
258
259# Prune registry tags only, keeping latest + 5 previous
260gordon images prune --registry --keep-releases 5
261
262# Inspect what prune would remove without applying
263# (also lists every skipped candidate with its reason)
264gordon images prune --dry-run
265
266# Skip confirmation prompt
267gordon images prune --no-confirm
268```
269
270## Required Permissions
271
272- The `list` subcommand requires `admin:status:read`.
273- The `prune` subcommand requires `admin:config:write`.
274- The `tags` subcommand requires `admin:status:read`.
275
276## Related
277
278- [CLI Commands](./index.md)
279- [Images Configuration](../config/images.md)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close