Container Registry¶
The verda registry commands manage the Verda Container Registry (VCR, vccr.io): configure credentials, browse repositories, push local Docker images, copy images between registries, and clean up. Registry credentials are stored separately from your API credentials (keys prefixed verda_registry_) while sharing the same profile system.
The parent command also accepts the aliases vccr and vcr — verda vcr ls is identical to verda registry ls.
Info
The registry command tree is beta. It's enabled by default (no env var required) and listed in verda --help as registry … (beta).
Command reference¶
| Command | Description |
|---|---|
verda registry configure |
Save VCR credentials (paste docker login, flags, or wizard) |
verda registry show |
Print credential status + expiry (no secrets) |
verda registry configure-docker (alias login) |
Write ~/.docker/config.json for docker pull / compose / helm |
verda registry ls |
List repositories in the active project |
verda registry tags <repo> |
List tags in a repository |
verda registry push [image…] |
Push local images (daemon / OCI layout / tarball) |
verda registry copy <src> [<dst>] (alias cp) |
Copy an image between registries |
verda registry delete [<target>] (aliases del, rm) |
Delete a repository or a single image |
Configure credentials¶
Create credentials in the Verda dashboard first: select your project → Credentials → Create credentials → provider Verda, give a name and an expiry, then Create credentials. The dialog shows three fields — the Registry authentication command is the most robust thing to copy, since it's the only place the registry URL appears.
Paste the full docker login command the UI prints (the host is extracted automatically):
verda registry configure \
--paste "docker login -u vcr-<project-id>+<cred-name> -p <secret> vccr.io"
Pass the name and secret separately (secret on stdin; --endpoint defaults to vccr.io on production):
echo -n "$SECRET" | verda registry configure \
--username vcr-<project-id>+<cred-name> \
--password-stdin
Or run the interactive wizard (no flags, on a terminal):
Show the active configuration and expiry (no secrets are printed):
verda registry show
# registry_configured: true
# expires_at: 2026-05-20T00:00:00Z
# days_remaining: 30
| Flag | Description |
|---|---|
--paste |
The full "Registry authentication command" from the web UI |
--username |
Full credentials name (vcr-<project-id>+<cred-name>) |
--password-stdin |
Read the secret from stdin |
--endpoint |
Registry host (defaults to the profile's saved host or vccr.io; required once for staging/custom) |
--expires-in |
Override the 30-day default expiry (in days) |
--profile |
Write to a named profile |
Warning
Credentials are write-once — Verda's API never returns the secret again, only the credential name. If the secret is lost, delete and recreate the credential in the web UI, then re-run configure. Re-running configure on a profile that already has registry credentials replaces them (with a confirmation prompt on a terminal).
Configure Docker¶
configure-docker (alias login) is a local file merge into ~/.docker/config.json so docker pull, Compose, Helm, and nerdctl can authenticate — it does not contact the registry. Existing entries for other registries are preserved.
verda registry configure-docker # merge the active profile
verda registry configure-docker --profile staging # a non-default profile
verda registry configure-docker --config /tmp/dc.json # a non-default docker config path
List repositories and tags¶
verda registry ls # repositories in the active project (interactive picker on a TTY)
verda registry ls | less # piping suppresses the picker — deterministic table
verda registry ls -o json # structured payload for scripts
verda registry tags my-app # tags + digest + size for one repository
verda registry tags my-app --all # don't cap the per-tag metadata
On a terminal, ls lists one row per repository and lets you pick one. Selecting a repository opens an action menu:
- Get pull URL — a filterable, newest-first tag picker; pick a tag and
lsprints the full copy-pasteable pull reference (vccr.io/<project>/<repo>:<tag>). - Delete image(s)… — the same multi-select + confirmation flow as
verda registry delete. - ← Back to the repository list.

tags <repo> opens the same tag picker on a terminal, or prints a per-tag table (digest / size) when piped or with -o json.

Info
An artifact is a unique manifest digest; a tag is a mutable label pointing at one artifact. Two tags on the same content count as one artifact. Use verda registry tags <repo> for a tag-centric view.
Push images¶
# from the Docker daemon
verda registry push my-app:v1.0.0
# multiple images
verda registry push my-app:v1 worker:v1 edge:v1
# override destination repo / tag (single image)
verda registry push my-app:latest --repo team/api --tag prod
# non-daemon sources
verda registry push --source oci ./build/image-layout
verda registry push --source tar ./out/image.tar
# interactive picker (no positional args, on a TTY)
verda registry push
# tuning
verda registry push my-app:v1 --jobs 4 --retries 5 --progress plain
--source auto (default) picks oci for directories, tar for *.tar/*.tar.gz/*.tgz, otherwise probes the Docker daemon. Running push with no arguments on a terminal launches an interactive picker — your local daemon images, or a guided OCI-layout/tarball prompt if the daemon isn't running.
| Flag | Description |
|---|---|
--repo / --tag |
Override the destination repository / tag (single-image push) |
--source |
auto (default), daemon, oci, or tar |
--jobs / --image-jobs |
Concurrency for layers / images |
--retries |
Retry attempts per layer |
--progress |
auto (default), plain, json, or none |
Copy images¶
copy (alias cp) copies an image from another registry into VCR. Run it with no arguments on a terminal for a guided wizard (source → access → scope → destination → confirm).

# single ref, default destination (VCR, src repo + tag preserved)
verda registry copy docker.io/library/nginx:1.25
# custom destination
verda registry copy gcr.io/project/app:v1 my-app:prod
# every tag in the source repository
verda registry copy docker.io/library/nginx --all-tags
# preview without writing
verda registry copy docker.io/library/nginx --all-tags --dry-run
# overwrite an existing destination tag without prompting
verda registry copy docker.io/library/nginx:1.25 --overwrite
The destination always uses your Verda credentials. The source side is controlled by --src-auth:
--src-auth |
Behavior | When to use |
|---|---|---|
docker-config (default) |
Reads ~/.docker/config.json (honors credsStore/credHelpers), falls back to anonymous |
You already ran docker login for the source host |
anonymous |
Sends no auth header | Public source, or to bypass a stale docker-config entry |
basic |
Basic auth from --src-username + secret on stdin |
CI / one-off credentials you don't want on disk |
Rule of thumb: if docker pull <src> works, verda registry copy <src> will read it — the keychain is identical.
# private source you've already `docker login`'d to
echo "$GHCR_PAT" | docker login ghcr.io -u USERNAME --password-stdin
verda registry copy ghcr.io/acme/private-app:v1 acme/private-app:v1
# inline basic auth (secret on stdin; never written to disk)
echo "$SRC_PASSWORD" | verda registry copy private.example.com/team/app:v1 \
--src-auth basic --src-username jdoe --src-password-stdin
Info
--all-tags uses partial-success semantics — one failing tag doesn't cancel the others. The command exits non-zero with registry_copy_partial_failure if any tag failed, and the structured payload carries total/succeeded/failed/skipped counts.
Delete repositories and images¶
verda registry delete my-app # whole repository (all artifacts + tags)
verda registry delete my-app:v1.2.3 # one image by tag
verda registry delete my-app@sha256:abcdef… # one image by digest
verda registry delete my-app:v1 --yes # skip the confirmation prompt
verda registry delete # interactive picker + multi-select (Space, Ctrl+A, Enter)
Danger
delete is irreversible and prompts for confirmation unless --yes/-y is passed. In agent mode --yes is mandatory (otherwise it returns a CONFIRMATION_REQUIRED error). Deleting an image by tag or digest removes the underlying artifact, so every tag pointing at that manifest is removed. If a Tag Immutability or Tag Retention rule blocks the delete, the CLI surfaces a registry_delete_blocked error explaining how to adjust the rule.
Profiles¶
Profiles work across API, S3, and registry credentials in the same ~/.verda/credentials file. With no --profile, registry commands use the active profile (verda auth use <name>, or VERDA_PROFILE), falling back to default.
verda registry configure --profile staging --paste "docker login ..."
verda auth use staging # subsequent registry commands target staging
Output formats¶
All commands honour the global output flags:
-o table(default) — human-readable-o json/-o yaml— a single structured payload (progress lines suppressed so output stays parseable)--agent— disables interactive prompts, implies structured output, and requires--yes/--overwritefor destructive operations--debug— dumps registry request/response metadata to stderr
Progress for push and copy is controlled by --progress (auto, plain, json, none) and always goes to stderr, so stdout stays clean for scripts.
Environment variables¶
| Variable | Description |
|---|---|
VERDA_REGISTRY_CREDENTIALS_FILE |
Override the default credentials path (~/.verda/credentials) |
DOCKER_CONFIG |
Honoured by configure-docker when --config is not passed |
DOCKER_HOST |
Honoured by the daemon source in push --source daemon/auto |