- GET /health/ready (Electrum connected, header < 1800s, scheduler heartbeat < 30s) is the
container healthcheck; the scheduler beats on every tick and draw-wait iteration
- GET /admin/electrum and an Electrum indicator in /admin (server, header age, last rotation)
- GET /admin/audit-log: before_id, event_type, round_id, user_id, from, to; the panel gets filters
- registration writes user_registered in its transaction
- the app's own logs also go to stdout; uvicorn trusts X-Forwarded-For from Caddy's fixed
address only, so the access log shows the client's IP
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- app runs as uid 1000; a one-shot data-permissions service chowns ./data to it
and closes it to others (works on an older root-owned install with no host sudo);
files are created 0600 (umask 077)
- python:3.12-slim and caddy:2-alpine pinned by digest; dependencies installed from
requirements.lock with --require-hashes
- the Fernet key is XPRV_ENCRYPTION_KEY_FILE (./secrets/xprv_encryption.key, a compose
secret), out of every environment variable and of a ./data backup
- setup.md no longer presents a second way to run the server (B-72)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Previously a missing master.xprv.enc only surfaced as a 500 on the
first register call, with a stack trace that didn't say what to do
about it. Check for the file before alembic/uvicorn start and exit 1
with the exact generate_master_key.py command to run.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
python:3.12-slim, installs the package (pip install .), runs pending
Alembic migrations before starting uvicorn. Migrations/alembic.ini/
scripts are copied in as-is (not part of the installed package) since
alembic and generate_master_key.py run directly against the source
tree.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>