isputnik-faces

isputnik-faces

Docker app from isputnik-faces' Repository

Overview

The face recognition engine for isputnik.home, in a container of its own: it finds the faces in the family's photos and describes each one, so isputnik.home can group them into people, name them and share photos by who is in them. Everything stays on your server, and the engine itself keeps nothing: a photo goes in, its faces come out. Runs on the CPU, with all cores but one so the server stays responsive during a scan. This is an add-on for isputnik.home and does nothing on its own: it has no sign-in, no pages and no data. Install it beside the isputnik container. Set it up from isputnik.home, on Control panel, Settings, Apps, Faces. Before installing, press Generate secret there and copy it (it is shown once); paste it into the Gateway Secret field below, which is required. Once the container runs, enter its address on the same page (http://[your Unraid IP]:4400 as installed here) and press Test connection, which then says Paired. Face recognition is then switched on per photo library under Control panel, Library, Libraries; the next scan uses it, and nothing is scanned twice. Needs isputnik.home 4.65.1 or newer.

isputnik.faces

An add-on for isputnik.home: its face recognition engine. It finds the faces in a photo and describes each one, behind the home server, which keeps every face, name and person and draws every screen. It requires the isputnik.home container, is installed beside it and is reached only through home's /faces gateway; this server has no pages and no data: a photo goes in, its faces come out, nothing is remembered.

Why it is a container of its own: the ONNX runtime and the two InsightFace models are ~450 MB that change about never, and home releases every few days. Here they are pulled once. The design is home's docs/face-engine-plan.md.

Status: 0.1.0, alpha. CPU only; a CUDA image is planned.

The contract, from this side

  • Reached only by home's server, signed with GATEWAY_SECRET in X-Isputnik-* headers (home's docs/apps-platform-plan.md → The contract); without the secret a request is anonymous. Home's gateway forwards only the admin window to browsers; /detect is called by home's own scanner.
  • The model id (buffalo_l/w600k_r50) is the one home stamps on its face rows, so an install that switches from in-process recognition re-embeds nothing.
  • The engine never calls home.
Route Who What
GET /faces/api/health anyone { ok, version, model, modelsPresent, loaded, providers, gpu }
GET /faces/api/me signed who home says this is — the Dashboard's signed probe
POST /faces/api/detect?crops=1 admin body: the photo's bytes (image/jpeg, png, webp, tiff, gif, avif, bmp; up to 64 MB). Answer: { model, width, height, faces: [{ box: [x, y, w, h], score, embedding, crop }] } — boxes normalised 0..1 of the upright image, embedding 512 float32 as base64, crop a 160 px WebP as base64 (or null with crops=0). 415 for a body that is not an image, 422 for one that will not decode, 503 while the recogniser is missing
GET /faces/api/admin/events, /log admin the admin's window, kept in memory
GET /faces/api/admin/backup admin 204 — nothing to hand over

Running it

docker network create isputnik          # once, shared with isputnik.home
docker run -d --name isputnik-faces --network isputnik \
  -e GATEWAY_SECRET=<the secret from Control panel → Settings › Apps → Faces> \
  ghcr.io/isputnikdotnet/isputnik.faces:latest

Then in isputnik.home: Control panel → Settings › Apps → Faces, address http://isputnik-faces:4400 (or http://<host IP>:4400 with the port published, http://<its IP>:4400 on br0 with a fixed IP), paste the same secret, Test connection. The image is ghcr.io/isputnikdotnet/isputnik.faces and, the same bytes, isputnikdotnet/isputnik.faces on Docker Hub; every release tag publishes both.

Unraid — the repository carries a Community Applications template, isputnik-faces.xml, listed in CA as isputnik-faces. It publishes port 4400 on bridge (safe: without the secret every request is answered 401), mounts nothing, and asks for the gateway secret, which is made in home first because the field is required.

Variable Default What
GATEWAY_SECRET — required in the image, at least 32 characters
ORT_THREADS cores − 1 CPU threads for the models and the decoder
ORT_PROVIDERS cpu execution providers to try first (cuda,cpu); CPU is always the last resort
WARM 0 1 loads the models on start
LOG_LEVEL info pino level
PUID / PGID 1000 who it runs as

Developing

npm install
npm run fetch:face-model     # the 167 MB recogniser, verified by SHA-256
npm run dev                  # :4400, no secret = the developer identity
npm test                     # the route tests; detection too once the model is there

To point a home checkout at it: FACES_URL=http://127.0.0.1:4400 and the same FACES_GATEWAY_SECRET / GATEWAY_SECRET on both.

Licence

AGPL-3.0-only, like isputnik.home. The models are InsightFace's (buffalo_l: SCRFD-500MF and the w600k_r50 ArcFace recogniser), under their own terms.

Requirements

Needs the isputnik (isputnik.home) container, version 4.65.1 or newer, installed on the same server. The engine is reached only through it.

Download Statistics

77
Total Downloads

Related apps

Details

Repository
ghcr.io/isputnikdotnet/isputnik.faces:latest
Last Updated2026-11-09
First Seen2026-11-10

Runtime arguments

Network
bridge
Shell
sh
Privileged
false
Extra Params
--stop-timeout=30

Template configuration

Engine PortPorttcp

The port the isputnik container reaches the engine on: enter http://[your Unraid IP]:[this port] as the Faces address in isputnik.home (Control panel, Settings, Apps). Not for browsers: the engine has no pages. On br0 with a fixed IP, or on a user-defined network shared with the isputnik container, this mapping is not used and the address is the container's own IP or name with port 4400.

Target
4400
Default
4400
Value
4400
Gateway SecretVariable

The secret isputnik.home signs its requests with, so this engine knows they come from it. Make it first, in isputnik.home on Control panel, Settings, Apps, Faces (Generate secret; it is shown once), and paste it here. Required: the engine refuses to start without one, or with one shorter than 32 characters. Everything else about face recognition is managed inside isputnik.home.

Target
GATEWAY_SECRET
CPU threadsVariable

How many CPU threads a scan may use. Left empty, all cores but one, so the box stays responsive while a scan runs; set 1 to throttle hardest, or a higher number to finish sooner. A CPU limit on the container works too.

Target
ORT_THREADS
Load models on startVariable

1 loads the models (about 200 MB of memory) when the container starts rather than at the first photo, so the first scan of the night does not wait on it.

Target
WARM
Default
0
Value
0
PUIDVariable

User ID the engine runs as. It runs unprivileged (not root) and writes nothing, so any user will do; 99 (nobody) matches the other isputnik containers.

Default
99
Value
99
PGIDVariable

Group ID the engine runs as.

Default
100
Value
100
Log LevelVariable

trace, debug, info, warn, error, fatal or silent. isputnik.home shows this log under Control panel, Overview, Logs.

Target
LOG_LEVEL
Default
info
Value
info