Files
volt/docs/registry.md
Karl Clinger 81ad0b597c Volt CLI: source-available under AGPSL v5.0
Complete infrastructure platform CLI:
- Container runtime (systemd-nspawn)
- VoltVisor VMs (Neutron Stardust / QEMU)
- Stellarium CAS (content-addressed storage)
- ORAS Registry
- GitOps integration
- Landlock LSM security
- Compose orchestration
- Mesh networking

Copyright (c) Armored Gates LLC. All rights reserved.
Licensed under AGPSL v5.0
2026-03-21 00:31:12 -05:00

6.6 KiB

Volt Registry

Volt includes a built-in OCI Distribution Spec compliant container registry backed by Stellarium CAS. Any OCI-compliant client — ORAS, Helm, Podman, Buildah, or Skopeo — can push and pull artifacts.

How It Works

The registry maps OCI concepts directly to Stellarium CAS:

  • Blobs — The SHA-256 digest from the OCI spec IS the CAS address. No translation layer, no indirection.
  • Manifests — Stored and indexed alongside the CAS store, referenced by digest and optionally by tag.
  • Tags — Named pointers to manifest digests, enabling human-readable versioning.

This design means every blob is automatically deduplicated across repositories, verified on every read, and eligible for CAS-wide garbage collection.

Licensing

Operation License Required
Pull (read) Free — all tiers
Push (write) Pro license required

Quick Start

Start the Registry

# Start on default port 5000
volt registry serve --port 5000

The registry is now available at http://localhost:5000.

Push an Artifact

Use ORAS or any OCI-compliant client to push artifacts:

# Push a file as an OCI artifact
oras push localhost:5000/myapp:v1 ./artifact.tar.gz

# Push multiple files
oras push localhost:5000/myapp:v1 ./binary:application/octet-stream ./config.yaml:text/yaml

Pull an Artifact

# Pull with ORAS
oras pull localhost:5000/myapp:v1

# Pull with any OCI-compliant tool
# The registry speaks standard OCI Distribution Spec

List Repositories

volt registry list

Check Registry Status

volt registry status

Authentication

The registry uses bearer tokens for authentication. Generate tokens with volt registry token.

Generate a Pull Token (Read-Only)

volt registry token

Generate a Push Token (Read-Write)

volt registry token --push

Custom Expiry

volt registry token --push --expiry 7d
volt registry token --expiry 1h

Tokens are HMAC-SHA256 signed and include an expiration time. Pass the token to clients via the Authorization: Bearer <token> header or the client's authentication mechanism.

Using Tokens with ORAS

# Generate a push token
TOKEN=$(volt registry token --push)

# Use it with ORAS
oras push --registry-config <(echo '{"auths":{"localhost:5000":{"auth":"'$(echo -n ":$TOKEN" | base64)'"}}}') \
  localhost:5000/myapp:v1 ./artifact

Anonymous Pull

By default, the registry allows anonymous pull (--public is enabled). To require authentication for all operations:

volt registry serve --port 5000 --public=false

TLS Configuration

For production deployments, enable TLS:

volt registry serve --port 5000 \
  --tls \
  --cert /etc/volt/certs/registry.pem \
  --key /etc/volt/certs/registry.key

With TLS enabled, clients connect via https://your-host:5000.

Read-Only Mode

Run the registry in read-only mode to serve as a pull-only mirror:

volt registry serve --port 5000 --read-only

In this mode, all push operations return 405 Method Not Allowed.

Garbage Collection

Over time, unreferenced blobs accumulate as tags are updated or deleted. Use garbage collection to reclaim space:

Dry Run

See what would be deleted without actually deleting:

volt registry gc --dry-run

Run GC

volt registry gc

Garbage collection is safe to run while the registry is serving traffic. Blobs that are currently referenced by any manifest or tag will never be collected.

Since registry blobs are stored in Stellarium CAS, you may also want to run volt cas gc to clean up CAS objects that are no longer referenced by any registry manifest, image, or snapshot.

Production Deployment

For production use, run the registry as a systemd service instead of in the foreground:

# Enable and start the registry service
systemctl enable --now volt-registry.service

The systemd service is pre-configured to start the registry on port 5000. To customize the port or TLS settings, edit the service configuration:

volt service edit volt-registry

CDN Integration (Pro)

Pro license holders can configure CDN integration for globally distributed blob serving. When enabled, pull requests for large blobs are redirected to CDN edge nodes, reducing origin load and improving download speeds for geographically distributed clients.

Configure CDN integration in /etc/volt/config.yaml:

registry:
  cdn:
    enabled: true
    provider: bunny       # CDN provider
    origin: https://registry.example.com:5000
    pull_zone: volt-registry

CAS Integration

The registry's storage is fully integrated with Stellarium CAS:

OCI Blob (sha256:abc123...)  ──→  CAS Object (/var/lib/volt/cas/objects/ab/abc123...)
                                        ↑
                                  Same object used by:
                                  • Container images
                                  • VM disk layers
                                  • Snapshots
                                  • Bundles

This means:

  • Zero-copy — pushing an image that shares layers with existing images stores no new data
  • Cross-system dedup — a blob shared between a container image and a registry artifact is stored once
  • Unified GCvolt cas gc cleans up unreferenced objects across the entire system

API Endpoints

The registry implements the OCI Distribution Spec:

Method Path Description
GET /v2/ API version check
GET /v2/_catalog List repositories
GET /v2/<name>/tags/list List tags
HEAD /v2/<name>/manifests/<ref> Check manifest exists
GET /v2/<name>/manifests/<ref> Get manifest
PUT /v2/<name>/manifests/<ref> Push manifest (Pro)
DELETE /v2/<name>/manifests/<ref> Delete manifest (Pro)
HEAD /v2/<name>/blobs/<digest> Check blob exists
GET /v2/<name>/blobs/<digest> Get blob
POST /v2/<name>/blobs/uploads/ Start blob upload (Pro)
PATCH /v2/<name>/blobs/uploads/<id> Upload blob chunk (Pro)
PUT /v2/<name>/blobs/uploads/<id> Complete blob upload (Pro)
DELETE /v2/<name>/blobs/<digest> Delete blob (Pro)

See Also