Documentation

Last updated: 2026-08-11

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 repocodeberg.org/apimeister/apimeister-photos
Short nameami
Pinned asa git dependency of backend-image-http (branch main)
XMP namespacehttp://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:

ConcernProvided by Everlock
Host routingThe HTTP frontend dispatches by Host to the right instance
PersistenceEach instance opens an Everlock versioned store instead of a plain directory
IdentityPassword login is backed by the Everlock user registry
AuthorizationEvery request is re-checked against http/image/<instance>
AI captioningami's inference provider is bridged to the shared AI runtime — no second model load
LAN discovery.local vhosts are announced over mDNS
Public TLSPublic 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 .local name (e.g. photos.local) is announced over mDNS and served plain HTTP;
  • localhost and 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.

images backend ami apimeister-photos immich