# HealthLog on TrueNAS SCALE HealthLog runs on TrueNAS SCALE as a Docker app: one `app` container from `ghcr.io/mbombeck/healthlog` and one PostgreSQL 16 database. The app container is stateless; everything you care about lives in the database dataset and in one value you must keep yourself: the encryption key. ## What the app needs | Setting | Value | | ------------ | ---------------------------------------------------------------------------------------- | | Image | `ghcr.io/mbombeck/healthlog`, tag `X.Y.Z` (amd64 and arm64) | | Port | `3000` (HTTP) | | User | runs as uid `1001`; no extra capabilities, `no-new-privileges` is fine | | Health check | `GET /api/health`, `200` when ready | | Start period | at least 60 s, with more retries than the image's 3 × 30 s: migrations run at every boot | | Database | PostgreSQL 16 (17 and later are not a drop-in), no extensions | | Volumes | none for the app; the database gets its own dataset | ## Environment | Variable | Required | Notes | | ----------------------- | -------- | ------------------------------------------------------------------------------------------- | | `DATABASE_URL` | yes | `postgresql://:@:5432/` | | `ENCRYPTION_KEY` | yes | 64 hex characters: `openssl rand -hex 32`. Keep a copy outside the NAS (see below). | | `API_TOKEN_HMAC_KEY` | yes | 64 hex characters, generated the same way. Changing it signs everyone out. | | `NEXT_PUBLIC_APP_URL` | yes | the address people open, for example `http://truenas.local:30180` | | `APP_URL` | yes | the same address | | `SESSION_COOKIE_SECURE` | no | `false` for a LAN install served over plain `http://`; leave unset behind an HTTPS proxy | | `HEALTHLOG_PLATFORM` | no | `truenas`: the admin's key backup step opens on the TrueNAS instructions | | `GEOLITE2_DIR` | no | a mounted directory of GeoLite2 `.mmdb` files, so sign-in locations are resolved on the NAS | `HEALTHLOG_PROCESS_TYPE` stays unset (`all`): one container serves the web app and runs the background jobs. ## Plain HTTP on the LAN Most NAS installs are reached over `http://`. Set `SESSION_COOKIE_SECURE=false` for that. If it is left at its default, the browser drops the sign-in cookie and the login page says so before you type a password: "This server only sets its sign-in cookie over https://". ## Back up your encryption key HealthLog encrypts tokens, notes, documents and in-database backups with `ENCRYPTION_KEY`. The key is not stored in the database. If the app is deleted and reinstalled with a new key over the old database dataset, the data is still there but cannot be read. 1. Copy `ENCRYPTION_KEY` from the app's settings (Apps, HealthLog, Edit, Environment) into your password manager. 2. Sign in as the admin and open Admin, Encryption. The step shows the key id and a fingerprint, the first 12 hex characters of SHA-256 over the key. Compare it with your copy: ```bash echo -n "" | xxd -r -p | sha256sum | cut -c1-12 ``` or paste the copy into "Check my copy" (it is compared and dropped, never stored or logged). 3. Confirm the backup. Until you do, admins see a reminder on the dashboard. After a key rotation the step comes back for the new key. ## When the key does not match the database At every start HealthLog checks that its key opens the data already in the database. If it does not, it refuses to serve instead of failing on every encrypted value: pages show "HealthLog cannot open its data", API requests answer `503` with `meta.errorCode` `encryption.key_mismatch`, `/api/health` answers `503` with `reason: "encryption_key_mismatch"`, and no background jobs run. TrueNAS shows the app as unhealthy rather than crashed, so the reason stays visible. Fix it one of three ways, then restart the app: 1. Put the original `ENCRYPTION_KEY` back. 2. Point `DATABASE_URL` at the database that belongs to this key. 3. Start fresh with an empty database. The old data and its backups need the old key. ## Updates Pick the new tag, take a snapshot of the database dataset first, and update. Migrations run on start; the first start of a new install applies all of them, which is why the start period above is generous.