Reddit Explorer¶
| Field | Value |
|---|---|
| ID | reddit-explorer |
| Status | active |
| Host | infra-services |
| Port | 8765 (Traefik network only) |
| URL | https://reddit-explorer.infra.realemail.app |
| Backup | Tier-1 PostgreSQL; tier-3 on-premises NFS media |
| Inventory | inventory/services/reddit-explorer.yaml |
Overview¶
Reddit Explorer is the always-on media review and archive workspace. Komodo
builds it from spadoople/reddit_explorer at /opt/reddit-explorer; PostgreSQL
remains on the existing LXC and media state remains on a dedicated Whrrr NFS
export. Finished zip parts move to /volume9/Prawns/4. Reddit/_reddit-explorer,
mounted into the web container as /library.
The web container stays a single Traefik replica. Gallery stills and
measurements run in a second container, reddit-explorer-media-worker
(REDDIT_EXPLORER_ROLE=gallery-media python server.py). It uses the same image
and compose.env. Its /data mount is the same NFS export
(/mnt/whrrr-reddit-explorer) read-only with rslave. It has no Traefik
labels and does not listen on 8765. The role is an environment variable
because --worker is a prefix of --workers and argparse would parse
gallery-media as the enrichment-worker count. Deploy this worker only after
the app image reads REDDIT_EXPLORER_ROLE. Until then the web process does
that work in-process, and this container's healthcheck stays unhealthy because
the heartbeat row is missing.
Gallery stills live on the local named volume reddit-explorer-stills, mounted
at /stills in the web container and the worker.
REDDIT_EXPLORER_GALLERY_STILLS_DIR=/stills is set on both.
REDDIT_EXPLORER_GALLERY_MEDIA_WORKER=external is set on the web container
only, so it does not run a second in-process worker. A one-shot
reddit-explorer-stills-init container chowns /stills to 10001:10001
before either service starts, then exits 0. Komodo ignores that service
(ignore_services on the reddit-explorer stack) so the exit does not mark
the stack unhealthy. Stills are regeneratable and stay on the Docker
host's local disk, not on the NFS media export.
The worker records liveness in two places, refreshed at least every 60 seconds:
app_settingskeygallery_media_worker_heartbeat.updated_atis unix seconds (valuemay repeat that timestamp).GET /api/healthon the web container reports the age of this row./stills/.heartbeat, a small file on the stills volume. Its contents are the same unix-second timestamp, and its mtime moves with each refresh.
The worker container healthcheck reads the app_settings row with psycopg
and REDDIT_EXPLORER_DATABASE_URL, the same pattern as the Order Ledger bot
heartbeat. It fails when the row is missing or older than 180 seconds. It does
not probe port 8765. The image's own healthcheck does probe that port;
compose replaces it for this service.
Property jobs (subreddit and user scans) run in a third container,
reddit-explorer-property-worker (REDDIT_EXPLORER_ROLE=property-worker
python server.py). Running them in the web process starved interactive
requests while a job was active. The worker uses the same image, compose.env,
user, and restart policy as the web container. It mounts the same /data and
/library NFS binds read-write with rslave. It joins traefik only for
egress to Reddit and PostgreSQL, has no labels, and does not listen on 8765.
REDDIT_EXPLORER_PROPERTY_JOBS=external on the web container stops it from
restoring or running jobs itself. The web still accepts start, pause, resume,
and cancel and records them in PostgreSQL, where the worker picks them up.
The property worker refreshes app_settings key property_worker_heartbeat
every 15 seconds (updated_at in unix seconds). Its healthcheck uses the same
psycopg pattern as the media worker and fails when the row is missing or
older than 120 seconds. Deploy it only after the app image knows the
property-worker role. An older image would not run jobs in either container.
The route is LAN/Tailscale-only and has a temporary, explicit ADR-002 exception from Authentik. It has no host port and must not receive a public Cloudflare record.
NFS tuning¶
/data and /library are separate Whrrr exports (/volume6 and /volume9),
so a file moved between them crosses infra-services twice. The
whrrr-reddit-explorer role tunes both mounts:
read_ahead_kbis raised to 16 MB on every pull. The kernel default of 128 KB held one read stream to 15-27 MB/s. 16 MB measured 66 MB/s on 2026-10-22, with load near 40 on infra-services.nconnect=4spreads NFS traffic over four TCP connections. It applies only to a fresh mount, so it takes effect after a reboot or after both Whrrr mounts are unmounted together.
To remount without a reboot, first stop every container that holds the binds, or the unmount reports the target busy:
Then remount with --tags reddit-explorer,nfs, recreate komodo-periphery,
and redeploy with the deploy-reddit-explorer Procedure.
Reddit Explorer builds 20261022.4 and later write zip parts into
/library/.reddit-explorer-staging, so Move to library is a rename instead
of a copy through this host.
Operations¶
The complete deployment, prerequisite, SOPS, backup, restoration, cookie secret, smoke-test, and troubleshooting procedures are in the service README.