Documentation
The apimeister-registry engine
Everlock's container registry is powered by apimeister-registry — a standalone, open-source OCI Distribution runtime. Everlock embeds that engine and wraps it in its own host routing, versioned storage, user model, and TLS, so the registry behaves like every other Everlock service.
This page explains what the upstream engine is, what it provides, and how Everlock configures it. It is the OCI counterpart of the apimeister-photos and gguf-runner engine pages.
Where it comes from
| Upstream repo | codeberg.org/apimeister/apimeister-registry |
| What it is | a generic, open-source OCI Distribution registry runtime |
| Pinned as | a git dependency of backend-oci-http |
| Also runs in | the downtozero cloud platform |
The crate is vendored as a normal Cargo git dependency, so the version Everlock
ships is whatever commit is pinned in Cargo.lock. To follow the engine itself,
track the upstream repository — Everlock consumes it rather than forking it.
What the engine provides
apimeister-registry implements the OCI Distribution API — the /v2/ HTTP
surface that docker, podman, buildah, skopeo, and other OCI clients
speak. From Everlock's side, the engine owns:
- the full
/v2/route surface and request handlers; - manifest and blob storage semantics, content-addressed by digest;
- blob upload sessions, including chunked and monolithic uploads;
- tag and repository listing;
- manifest and blob deletes;
- the
RegistryRuntimethat ties these together.
What makes it embeddable is that the engine keeps its three external concerns behind traits, so the host application supplies the implementations:
| Trait | Responsibility |
|---|---|
RegistryStorage | where blobs and manifests are persisted |
RegistryAuthProvider | who the caller is and what they may do |
RegistryPolicy | registry-wide rules (anonymous pull, auto-create, delete) |
This is the seam Everlock plugs into.
How Everlock embeds it
Everlock mounts the engine through backend-oci-http and supplies all three
trait implementations from its own primitives.
flowchart TD
Client["docker / podman / OCI client"] --> FE["frontend-http (host routing, TLS, ACME)"]
FE --> BE["backend-oci-http (per-host registry selection)"]
BE --> ENG["apimeister-registry (/v2 OCI Distribution API)"]
ENG -->|RegistryStorage| ST[("Everlock versioned store, one per registry")]
ENG -->|RegistryAuthProvider| US["Everlock users and grants"]
ENG -->|RegistryPolicy| POL["Everlock registry policy"]| Concern | Provided by Everlock |
|---|---|
| Host routing | frontend-http dispatches by Host to the right registry instance |
| Persistence | each registry opens its own Everlock versioned store via a RegistryStorage adapter |
| Identity | HTTP Basic credentials are checked against the Everlock user registry |
| Authorization | every request maps to a grant on http/oci/<instance> |
| Public TLS | public registry vhosts get ACME certificates automatically |
| Multi-tenancy | one process serves many isolated registries, each its own store and vhosts |
Because storage and identity are Everlock's, a pushed image becomes ordinary Everlock store writes (and therefore Git commits), and registry access uses the exact same users and grants as the rest of the system. The OCI protocol code itself stays in the shared engine.
How Everlock configures it
Everlock sets the engine's policy and wires each registry instance; the rest is standard OCI behaviour.
Registry policy
Everlock supplies a RegistryPolicy with deliberately conservative defaults:
| Policy | Everlock setting | Effect |
|---|---|---|
| Anonymous pull | off | a request with no credentials is evaluated as the built-in anon user, and only succeeds where anon holds a grant |
| Repository auto-create | off | repositories are not implicitly created by a push to an unknown name |
| Delete | on | manifest and blob deletes are allowed, gated by the Everlock Owner/delete grant |
Public read access is therefore expressed the Everlock way — by granting
Reader on the instance to anon — rather than by a registry-wide "anonymous
pull" switch:
/users grant anon http/oci/main reader
Registry instances
Each registry instance is one block in config/oci-http.toml, with its own
store and vhosts:
enabled = true [registries.main] store = "everlock-oci-main" vhosts = ["registry.example.com"] [registries.staging] store = "everlock-oci-staging" vhosts = ["registry-staging.example.com"]
Instances are also managed from the admin console (/oci list, /oci create,
/oci set, /oci unset, /oci delete). For the full configuration surface,
access-path mapping, and request flow, see the
registry model and auth reference. For a first push and
pull from docker, start with
Getting started: OCI registry.