Documentation

Last updated in git: 2026-06-11

Getting started: OCI registry

This guide walks through a local first run of Everlock's OCI backend:

  • start Everlock with one OCI registry bound to localhost
  • create a user through the admin SSH console
  • log in with Podman
  • push a sample image
  • pull it back again

This uses the current implementation exactly as it exists today:

  • one OCI registry selected by vhost
  • Everlock HTTP Basic auth
  • access scoped to the OCI instance
  • optional public pull through the built-in anon user

1. Start Everlock with OCI enabled

For a local first pass, start Everlock with:

  • the HTTP frontend enabled
  • the admin SSH backend enabled
  • one bootstrap OCI registry
  • localhost as the OCI vhost
everlock serve \
  --frontend-http \
  --frontend-http-listen-http 127.0.0.1:8080 \
  --backend-admin-ssh \
  --backend-oci-http \
  --backend-oci-http-vhost localhost \
  --backend-oci-http-store everlock-oci-local \
  --admin-user admin \
  --admin-password change-me

What this does:

  • starts Everlock on 127.0.0.1:8080
  • enables one OCI registry reachable as localhost:8080
  • stores OCI data in the everlock-oci-local Everlock store
  • bootstraps an admin user for the SSH admin console

The OCI backend is host-routed, so the vhost matters. Without it, the registry would not be reachable.


2. Open the admin console

Connect over SSH:

ssh -p 2222 admin@localhost

Enter the bootstrap password:

change-me

You should land in the Everlock admin REPL:

Everlock Admin
>

3. Create a registry user

Create a normal user that will push and pull images:

/users add alice change-me

Grant the user write access to the OCI instance:

/users grant alice http/oci/default writer

The bootstrap OCI registry created by --backend-oci-http-vhost uses the logical instance name default.


4. Log in from Podman

Use Podman against the plain HTTP local registry:

podman login --tls-verify=false localhost:8080

Login with:

  • username: alice
  • password: change-me

The current backend uses HTTP Basic auth backed by the Everlock user registry.


5. Push a sample image

Pull a small public image first:

podman pull docker.io/library/alpine:3.20

Tag it for the Everlock registry:

podman tag docker.io/library/alpine:3.20 localhost:8080/alpine:demo

Push it:

podman push --tls-verify=false localhost:8080/alice/alpine:demo

6. Pull the image back

Remove the local copy first so the next pull really comes from Everlock:

podman rmi localhost:8080/alpine:demo

Now pull it back from Everlock:

podman pull --tls-verify=false localhost:8080/alpine:demo

If the pull succeeds, your Everlock OCI backend is working end to end:

  • HTTP frontend
  • host dispatch
  • Everlock auth
  • OCI runtime
  • Everlock store-backed persistence

7. What is happening under the hood

Current behavior:

  • frontend-http accepts the request on port 8080
  • backend-oci-http selects the registry by Host: localhost
  • Everlock validates alice through HTTP Basic auth
  • Everlock maps the request to the access path http/oci/default
  • the shared apimeister-registry OCI router handles /v2/...
  • OCI data is stored in the everlock-oci-local Everlock store

Current limitation:

  • authorization is still coarse-grained at http/oci/<instance>
  • there is no repository-level OCI ACL model yet

8. Current operator caveats

  • OCI registries can be managed through /oci ... in the admin SSH console.
  • Multi-registry setups are stored in config/oci-http.toml.
  • OCI config changes currently apply on restart rather than live reload.
  • Public pull is granted by giving Reader on the OCI instance to the built-in anon user.
  • The current backend is store-backed, so large image traffic will create many store commits.
  • A usable OCI registry requires at least one configured vhost.

9. Make the registry publicly readable

If you want anyone to be able to pull from the OCI instance without logging in, grant Reader on the instance to the built-in anon user:

/users grant anon http/oci/default reader

For the bootstrap registry started with --backend-oci-http-vhost, the instance name is default.

After that, unauthenticated pulls work:

podman pull --tls-verify=false localhost:8080/alpine:demo

Read next

oci registry getting-started