summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorKen D'Ambrosio <ken@jots.org>2026-06-08 18:36:07 +0000
committerKen D'Ambrosio <ken@jots.org>2026-06-08 18:36:07 +0000
commit625b3d5176f2c274e91fcf28bda8e45cc0477722 (patch)
tree6ca16ad6f4a830b65dcddbd78ad7e7a2f1655682 /README.md
parentecc872a1fd43c0863e3171a1faf533adc3e3a4c5 (diff)
Separate face detection into standalone daemon
- Strip all face code from update.rb; add shared log helper writing to /opt/albumen/log/albumen.log with [update] prefix. update.rb now owns only album.json; face_daemon.rb owns faces.json. - New scripts/face_daemon.rb: polls MEDIA_ROOT for unprocessed images, calls faces.py in batches, writes per-directory faces.json sidecars atomically. Graceful SIGTERM/SIGINT shutdown between directories. - New config/face_daemon.service: systemd unit running as albumen user, Restart=on-failure, logs via SyslogIdentifier=albumen-faces. - app.rb: add FACES_ENABLED constant; load_faces() helper reads faces.json; album_files() merges face data into each entry as :faces field. - Update README.md and DESIGN.md to document the new daemon architecture, faces.json schema, and service management commands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'README.md')
-rw-r--r--README.md41
1 files changed, 30 insertions, 11 deletions
diff --git a/README.md b/README.md
index 8167c0b..c7a66fd 100644
--- a/README.md
+++ b/README.md
@@ -36,8 +36,9 @@ back end, plain HTML/CSS/JS front end. Live at **https://albumen.jots.org**.
**Force rescan all** checkbox bypasses the sentinel and rescans every directory
### Facial recognition (opt-in)
-- Detects faces in photos and stores 128-D embeddings alongside each image
-- Powered by [face_recognition](https://github.com/ageitgey/face_recognition) (dlib/HOG, CPU-only)
+- Detects faces in photos and stores 128-D embeddings in per-directory `faces.json` sidecar files
+- Powered by [face_recognition](https://github.com/ageitgey/face_recognition) (dlib CNN model, CPU-only)
+- Runs as a background daemon (`face_daemon.service`), completely decoupled from the update script
- People management and browse-by-person UI in progress
### Media support
@@ -176,7 +177,9 @@ The PBKDF2-SHA256 hash is stored in `/opt/albumen/config.yml` (readable only by
## Facial recognition setup
-Face detection is opt-in. Install once, then enable in `config.yml`.
+Face detection is opt-in and runs as a **separate background daemon** so it
+never slows down the update script. Photos are indexed and browseable
+immediately after upload; faces are detected asynchronously in the background.
### 1. Install Python dependencies (server, ~30 min first time)
@@ -193,31 +196,47 @@ Add to `/opt/albumen/config.yml`:
```yaml
faces:
enabled: true
+ workers: 20 # parallel threads (set to ~nproc/3 to leave headroom)
+ poll_interval: 300 # seconds between full sweeps
```
-### 3. Run the update script
+### 3. Install and start the daemon
```bash
-ruby /opt/albumen/scripts/update.rb
+cp /opt/albumen/config/face_daemon.service /etc/systemd/system/
+systemctl daemon-reload
+systemctl enable face_daemon
+systemctl start face_daemon
```
-The update script will now detect faces in images and store bounding boxes and
-embeddings in each album's `album.json`. This is a one-time cost per image;
-subsequent runs skip already-processed photos.
+The daemon polls the media tree every `poll_interval` seconds, processes any
+images not yet in a `faces.json` sidecar, and logs to
+`/opt/albumen/log/albumen.log` with a `[faces]` prefix.
+
+Initial detection of a large library (~20,000 photos with CNN model on a
+64-core CPU) takes roughly 2.5–3.5 days. Only new photos are processed on
+subsequent passes.
---
## Service management
```bash
+# Web app
systemctl status albumen # is it running?
systemctl restart albumen # restart (e.g. after editing app.rb)
journalctl -u albumen -f # live service logs
-tail -f /opt/albumen/log/puma.stdout.log # Puma access log
-tail -f /opt/albumen/log/puma.stderr.log # Puma error log
+
+# Face detection daemon
+systemctl status face_daemon # is it running?
+systemctl restart face_daemon # restart the daemon
+journalctl -u albumen-faces -f # live daemon logs (systemd journal)
+
+# Shared activity log (both update.rb and face_daemon.rb write here)
+tail -f /opt/albumen/log/albumen.log
```
-The service runs as the `albumen` user. App code lives in `/opt/albumen/`.
+Both services run as the `albumen` user. App code lives in `/opt/albumen/`.
---