Documentation
The apimeister-photos engine (ami)
Everlock does not implement a photo library from scratch. The image backend embeds apimeister-photos — a standalone, stateless media library known informally as ami — and wraps it in Everlock's host routing, user model, storage, and AI runtime.
This page explains what the upstream engine is, what it brings to Everlock, and
which of its features you can configure from config/image-http.toml.
Where it comes from
| Upstream repo | codeberg.org/apimeister/apimeister-photos |
| Short name | ami |
| Pinned as | a git dependency of backend-image-http (branch main) |
| XMP namespace | http://apimeister.com/ami/1.0/, prefix ami: |
The crate is vendored as a normal Cargo git dependency, so the version Everlock
ships is whatever commit is pinned in Cargo.lock. To track upstream changes,
follow the repository directly — Everlock re-exports the engine but does not fork
it.
What the engine provides
ami is a complete media library on its own. The pieces Everlock surfaces are:
- Immich API compatibility — the same REST surface as Immich, so existing Immich mobile and desktop clients work against an Everlock image instance without modification.
- Embedded XMP as the source of truth — all canonical metadata (tags, albums, descriptions, GPS, capture time, live-photo links) is written into the original asset file as XMP. There is no SQLite file, no sidecar database, and no metadata store that can drift from the files.
- Rebuildable indexes — search indexes and caches are derived. If they are lost, ami can reconstruct them by walking the files and re-reading embedded XMP.
- Disposable derivatives — thumbnails and previews are regeneratable JPEG derivatives, never canonical.
- Live-photo pairs — an image and its companion video are treated as one atomic unit for album membership, deletion, and moves.
- A built-in web gallery — the browser UI you reach at the instance vhost.
- A background job runner — used for preview generation, duplicate detection, and AI metadata enhancement.
For the on-disk format, the full domain operation list, and the Immich ID translation rules, see the internal image backend reference — this page focuses on configuration.
What Everlock adds on top
The engine is stateless and transport-agnostic. Everlock supplies the parts ami deliberately leaves out:
| Concern | Provided by Everlock |
|---|---|
| Host routing | The HTTP frontend dispatches by Host to the right instance |
| Persistence | Each instance opens an Everlock versioned store instead of a plain directory |
| Identity | Password login is backed by the Everlock user registry |
| Authorization | Every request is re-checked against http/image/<instance> |
| AI captioning | ami's inference provider is bridged to the shared AI runtime — no second model load |
| LAN discovery | .local vhosts are announced over mDNS |
| Public TLS | Public vhosts get ACME certificates automatically |
Crucially, ami's own login, cookie, bearer-token, presigned-key, and OIDC flows still run inside the embedded router. Everlock does not replace those protocol details — it wraps the whole mounted router in an outer authorization layer and delegates the password check to the Everlock user registry. The outer layer stays authoritative, so revoking a grant takes effect even for tokens ami already issued.
Configuring the engine
Engine-level options are set per instance in config/image-http.toml. A
fully-populated instance block looks like this:
[instances.family] # Everlock store that holds this instance's media (required) store = "family-images" # Hostnames that route to this instance (required for a usable instance) vhosts = ["photos.example.net", "photos.local"] # Override the advertised base URL. Derived from the first vhost when unset. public_url = "https://photos.example.net" # Display name shown inside the gallery UI and API. Defaults to the engine's # own default when unset. instance_name = "The Family Album" # BCP 47 language tags for AI-generated captions and descriptions. # Empty (the default) means English only. enhance_languages = ["en", "de"]
store
The Everlock store backing this instance. Required. Each instance must use its own store — two instances pointing at the same store is not a supported configuration. See Versioned storage.
vhosts
The hostnames that route to this instance. A usable instance needs at least one. The kind of hostname determines how it is reached:
- a public DNS name (e.g.
photos.example.net) becomes ACME-managed HTTPS; - a
.localname (e.g.photos.local) is announced over mDNS and served plain HTTP; localhostand raw IPs stay plain HTTP for local use.
One instance can mix all three — for example a public name for remote access and
a .local name for the home network.
public_url
The absolute base URL the engine advertises to clients (used in API responses
and share links). When unset it is derived as https://<first-vhost>. Set it
explicitly when the public scheme or port differs from that default — for
instance when Everlock sits behind another reverse proxy, or when the primary
vhost is a .local name reached over plain HTTP on a custom port.
instance_name
A human-facing label for the gallery, shown in the engine's UI and API. Purely
cosmetic; it does not affect routing or the Everlock access path (which is
always http/image/<instance>, keyed by the TOML table name, not this label).
enhance_languages
Controls the languages of AI-generated metadata. ami's enhance-metadata job
asks the shared AI runtime to caption new uploads; this list selects the output
languages as BCP 47 tags. Empty means English only. This setting has no effect
unless an AI runtime is available — see AI captioning and
the captioning section below.
AI captioning
When the AI backend is enabled, backend-image-http looks up the
shared image-inference provider in the backend registry and bridges it into
ami's enhance-metadata job. Newly uploaded photos are captioned by the same
in-process model that serves the admin SSH /ai shell — Everlock's own
gguf-runner inference engine running an embedded
vision model. It reuses the one already-loaded model, and captioning runs
entirely on the local machine.
If the embedded AI runtime fails to load, captioning is silently disabled and
the rest of the image backend keeps working. Use
enhance_languages to choose the caption languages once a
runtime is available.
Federation
The engine supports album federation between ami instances (subscribe to a remote album by presigned key, then sync bidirectionally with most-recent-wins conflict resolution). This is an engine feature stored in the asset metadata; Everlock does not add configuration for it today. See the federation notes in the internal image backend reference.