Run the engine
One command, one door, and the two flags worth setting from the start.
The wizard does this for you. This page is what it does, for when you would rather do it yourself.
nils serve --bind 127.0.0.1:8437 \
--registry /srv/nils/registry \
--pack-dir /srv/nils/packs
It prints one line and stays in the foreground:
nils serve 127.0.0.1:8437 auth off workers 4 registry /srv/nils/registry
The door
Everything the engine can do is one HTTP API on that address, and the door that describes it is:
curl -s http://127.0.0.1:8437/api/capabilities
It answers with the engine’s version, the contract versions it speaks, the packs it loaded, the registry’s id and epoch, who you are, and the list of every other door. The desk shows you the same document; nothing in NILS is discovered by guessing.
The contract
The API is versioned as a whole, and the version is 7. Each version is a document of its own, published beside the ones before it and left as it stands, so what a caller was written against does not move underneath it. Version 7 is version 6 with the doors of models, derivatives, picks, campaigns, label sets and pipelines added. Since its release it has only been amended in place with additions (new doors, new fields and new values), never by changing or removing what was there, so a caller written against an earlier state of version 7 meets the engine it already knew. Version 6 added one door, GET /api/pseudonymize/tags, what the pseudonymiser does to the standard elements.
The documents are in the engine’s source under contracts/openapi/, one directory per version, and nils-desk check compares the versions an engine speaks with the desk’s own.
Flags worth setting
--backup-dir /srv/nils/backups is where the backup job writes archives. Without it, backup and verify are refused rather than writing somewhere surprising. From the command line, nils backup with no --dir writes to the backup place that the registry’s own place names. A registry kept in Postgres is backed up with pg_dump, which the engine’s image carries; on a machine, install the PostgreSQL client.
--ingest-root source=/data/source names a location a queued digest may refer to as @source/relative. The engine never composes a path a caller sends it, so a digest from the desk can only name a root you registered. The flag repeats.
--worker runs the jobs the doors queue, such as a digest or a backup started from the desk, beside the doors. The queue has three lanes, worked side by side: the main one, the pipeline runs, and the pictures (the previews and 3D views a sort leaves to make), so a long run or a picture build never holds up a read. Without it a queued job waits until someone runs nils jobs work. With --backup-dir as well, it queues the backups the registry’s schedule asks for; see backups.
nils serve --bind 127.0.0.1:8437 \
--registry /srv/nils/registry --pack-dir /srv/nils/packs \
--backup-dir /srv/nils/backups --worker \
--ingest-root source=/data/source
Bind address
127.0.0.1 means only that machine can reach the engine, which is what makes --auth off safe. Anything else needs a way of knowing callers and, in practice, the desk in front of it. The engine is not meant to face a network on its own.
Workers
--workers N sets how many requests are handled at once, each with its own connection to the registry; four by default. A machine that serves a group wants roughly as many as it has cores, and --event-streams caps the live update streams (half the workers by default).
Next: who may call it.
Updated 17 October 2026