Operator scenarios¶
Quick map from what you want to do → the right wiki page, plus end-to-end journeys that string pages together.
Use this after Install and First login.
End-to-end journeys¶
These are the stories the rest of the wiki supports. Walk them on a lab host before production.
Journey A — New instance to first healthy host¶
Goal: PiHerder is up; one Pi is keyed and visible on the dashboard.
| Step | Action | Why |
|---|---|---|
| 1 | Install + secrets | Stack + encryption key for fleet secrets |
| 2 | First login | First account becomes admin; registration locks |
| 3 | Optional HTTPS | Trust for browsers and later push |
| 4 | Add a server | Wizard — Identity → Trust → Connect (install key → test → clear password) |
| 5 | Wizard Features (or Edit → Features) | Enable only backups / OS updates (or HA updates) / Docker you need |
| 6 | Open Dashboard | Confirm the host appears; no mystery tiles yet |
Done when: Server detail shows green-enough SSH/deps for enabled features; no password left stored if key auth works.
Optional polish: pin the host Overview/Docker and Network Hosts map (Pins & host jump) so the ★ menu opens the map graph (#map).
Journey B — Safe backup before you depend on it¶
Goal: One successful rsync backup and a dry-run restore you understand.
| Step | Action | Why |
|---|---|---|
| 1 | Enable Backups on the server | Feature flag gates UI and bulk |
| 2 | Add source paths on Backups | PiHerder only copies what you list |
| 3 | Run backup now | Proves Celery + rsync + path policy |
| 4 | Open Jobs | See pending → running → success |
| 5 | Restore wizard → dry-run | See reverse rsync without writing |
| 6 | Only then schedule cron | Avoid automated failure noise |
Done when: last_backup_at updates; Audit shows request → complete; you know where files land on the herder host (Volumes).
Journey C — Patch without silent upgrades¶
Goal: Know what needs attention; apply only when you choose.
| Step | Action | Why |
|---|---|---|
| 1 | Enable OS patch and/or Docker | Flags unlock check/apply |
| 2 | Run check only (Updates) | Safe: counts packages/images, no upgrade |
| 3 | Read Dashboard “need attention” | Aggregate view of the fleet |
| 4 | Manual apply on one host | Live log; exclusive job per type |
| 5 | Optional: schedule checks weekly | Always-on awareness |
| 6 | Optional later: schedule apply with “only if updates” | Never silent default auto-upgrade |
Done when: You can explain check vs apply, and Jobs shows who/what for both.
Journey C2 — HAOS appliance under PiHerder¶
Goal: Home Assistant OS is a managed host: keyed SSH, HA update check, System info, optional backup.
| Step | Action | Why |
|---|---|---|
| 1 | Enable Terminal & SSH on HAOS; install rsync if you want backups | Path prerequisites |
| 2 | Add a server as root (or add-on user) + deploy key | Fleet record |
| 3 | Host profile HAOS (or auto-mark after check) | Backend uses ha CLI |
| 4 | Enable HA updates (+ Backups if needed); leave Docker off | Capability envelope |
| 5 | System info + Check HA updates | Versions + component counts |
| 6 | Optional: manual HA update… in a maintenance window | Same confirm/audit bar as OS patch |
Full detail: HAOS hosts.
Done when: HAOS chip + real Core/OS/Supervisor versions; check job green.
Journey D — Deploy a known stack from a template¶
Goal: Uptime Kuma (or NPM / Pi-hole / Grafana) runs from Catalog → Templates.
| Step | Action | Why |
|---|---|---|
| 1 | Host has Docker feature + working docker | Deploy target |
| 2 | Templates overview → OOTB badge pack | Versioned recipe, not a one-off paste |
| 3 | Deploy wizard | Variables, host, preview; deploy runs as Job + live log (0.6+) |
| 4 | Post-deploy checklist | DNS, first login, bind integrations |
| 5 | Optional: Kuma integration | Status in fleet Services |
| 6 | Later: Check drift / redeploy / Accept host as desired | Desired state stays authoritative; intentional host edits get adopted |
Done when: Deployment page exists; Docker shows the project; secrets only via step-up if required.
Journey D2 — Capture an existing stack (from host)¶
Goal: Turn a running compose project (e.g. grafana-monitoring with promtail-config.yaml) into a Yours template you can redeploy elsewhere.
| Step | Action | Why |
|---|---|---|
| 1 | Host Docker inventory shows the project | Source of truth on the Pi |
| 2 | From host — pick server + project | Pull over SSH |
| 3 | Review editor: compose, Additional files, variables (NODE_NAME, ports, volumes, remote URLs) | Config sidecars + host labels parameterised |
| 4 | Save → badge Yours | Never overwritten by OOTB pack refresh |
| 5 | Deploy to another host with a different NODE_NAME | Same recipe, correct labels/endpoints |
Done when: Template lists under Your templates; deploy writes compose + sidecar files; labels match the target host.
Journey Move — Compose project to another host¶
Goal: An unlocked stack (Grafana-class) runs on dest with its data, name, and maps. Requires PIHERDER_SERVICE_MIGRATE=true and two Docker hosts (v1.4.0, flag off by default).
| Step | Action | Why |
|---|---|---|
| 1 | Enable the flag; recreate web | Kill switch default off |
| 2 | Lock a hardware-bound stack (or HAOS) | Prove Move is refused |
| 3 | Unlock a disposable stack; ⋯ → Move to another host… | Wizard |
| 4 | Pick dest (wait modal) · remap dest name/ports if needed · read preflight | Blocks before copy; dest name/port overrides clear name/port clashes |
| 5 | Confirm downtime → JobHold | Stop → copy → dest up → name/proxy. Copy/dest-up fail: Start source stack |
| 6 | Check dest inventory, CNAME or NPM forward_host, maps, Grafana container chips | Green cutover |
| 7 | Leave leftover stopped on the first run | Data still on source |
Full page: Move a service. Do not pick Remove source on a stack you still need. Tick Adopt into fabric only if an NPM-only name should appear on the DNS list (Pi-hole CNAMEs stay).
Journey E — Homelab map (DNS + proxy + certs)¶
Goal: Names, paths, and TLS are visible and mostly automated.
| Step | Action | Why |
|---|---|---|
| 1 | Pi-hole + optional NPM | DNS truth + edge proxy inventory |
| 2 | Host Edit → General FQDN + manage A | A records fan out to Pi-holes |
| 3 | Network maps settings | LAN/gateway so Hosts map is readable |
| 4 | Adopt / import names from Pi-hole | Bring existing lab DNS into PiHerder |
| 5 | Certificates pull or upload | Vault + maps → deploy to hosts |
| 6 | Dashboard network panel | Cheap pulse of named/mapped/NPM counts |
Done when: Hosts map shows home vs cloud; a cert map can redeploy PEMs after renew.
Journey F — Disaster recovery for PiHerder itself¶
Goal: You can rebuild a fully functional control plane (keys, users, maps, integrations) after losing the herder host — and you know honestly what is not in that pack.
| Step | Action | Why |
|---|---|---|
| 1 | Offline copy of PIHERDER_MASTER_KEY | Encrypted fields useless without it |
| 2 | Self-backup Full DR once (v1.2+ = pg_dump) | Entire herder DB + logos — not rsync trees. Pre-1.2 “full” was JSON only. |
| 3 | Read Honest DR scenarios on that page | Scenario A (min) vs C (comfort pack) |
| 4 | Schedule herder backup | Regular DR hygiene |
| 5 | Know Volumes | piherder_backups ≠ fleet /backups |
| 6 | Optional: copy fleet backup disk + edge ./certs | File DR + herder HTTPS without re-issue |
| 7 | Practice dry-run restore on a lab stack with the same master key | Confidence before a real outage |
Done when: Master key + at least one Full archive live off the herder host; you can explain “v1.2 Full = whole DB / host rsync no”; restore dry-run understood.
Not done when: You only backed up the herder and expect Frigate recordings or every nmap XML to reappear — those are out of self-backup scope (see Self-backup — not included).
Journey G — Second operator with least privilege¶
Goal: Someone else can run fleet jobs without full admin.
| Step | Action | Why |
|---|---|---|
| 1 | Roles | viewer vs operator vs admin |
| 2 | Users create operator | Invite + one-time password |
| 3 | Optional force 2FA | Policy for the whole instance |
| 4 | Operator runs a backup/check | Confirms RBAC allows fleet mutate |
| 5 | Confirm they cannot open herder restore | Control plane stays admin-only |
| 6 | Optional: SSO + passkey | Same 2FA gates after IdP |
Journey I — 1.2 identity + optional console¶
Goal: Harden sign-in (passkey / optional SSO) and decide whether web SSH is on.
| Step | Action | Why |
|---|---|---|
| 1 | Account → Add passkey (+ TOTP still OK) | Second factor without an app-only story |
| 2 | Optional Settings → SSO | BYO IdP; keep an admin password |
| 3 | Leave PIHERDER_SSH_CONSOLE=false unless you need a browser shell | Default off; XSS on the herder origin is shell-equivalent when on |
| 3b | Leave PIHERDER_HOST_FILES=false until you want jailed SFTP | Default off; Host Files |
| 3c | Leave PIHERDER_SERVICE_MIGRATE=false until you want host→host copy | Default off; Move a service |
| 4 | If you enable it: Settings → Console for idle / max / slots; Security for 2FA grant | Web SSH console · Settings |
| 5 | Then: operator + 2FA → Console → + Shell | Same wiki |
| 6 | Test connection pins the host key; reset only after a rebuild | TOFU — mismatch is refused |
| 7 | Smoke the v1.2 QA identity + console rows if you turn these on | Optional surfaces — they stay off until you enable them |
Journey H — LAN discovery (opt-in nmap)¶
Goal: See the whole LAN (fleet + everything else) without auto-enrolling 50 devices as managed servers.
| Step | Action | Why |
|---|---|---|
| 1 | Build + start nmap worker (--profile nmap); fence is compose-owned (PIHERDER_NMAP_WORKER) | Web never runs nmap |
| 2 | LAN Discovery integration + CIDR(s) | Scope allowlist |
| 3 | Overview → Scan now modal → Discovery, then Inventory (ports); detailed/deep needs in-app confirm | Trust before schedules; Cancel does not queue |
| 4 | Devices → List or Map → edit modal: map name, device type, gateway if router, Mark known | Labels + kind + Router spine + inbox |
| 5 | Catalog → Network → Hosts map — radar Discovered, 1:1 fit; lock a host or cam for ports (tap callout → list); clear focus when done | End-to-end view + progressive ports; no per-device link required for discovered chips |
| 5b | Optional: server detail — always-open LAN discovery card beside Network path → Edit device → Save/close returns to that server | Soft-embed without Integrations detour |
| 6 | Optional: Path map — select NPM hub to light all proxied paths + connectors | Access picture for via-proxy names |
| 7 | Link / promote only what you will manage | Discovery ≠ fleet member |
| 8 | Optional schedules (create + Edit) | Cadence you control |
| 9 | Optional Runs tab | History by intensity + Job link (no run ID column) |
| 10 | Optional vuln pack update + deep scan | Pack volume opt-in |
Done when: Hosts map shows fleet + discovered chips; named devices read clearly; known/type/gateway are set where needed; you know how to link/promote; schedules stay off until you want them.
First week (quick links)¶
| Scenario | Doc |
|---|---|
| Compose install + secrets | Install |
| Register first admin (no default user), then invite others | First login · Users |
| Trusted HTTPS for PWA/push | HTTPS & TLS |
| Light / dark theme | Appearance |
| About PiHerder / GitHub / new version notice | Avatar menu → About (/about) |
| Add a Pi, deploy SSH key, features (wizard) | Add a server · Journey A |
| HAOS appliance (SSH + HA updates) | HAOS hosts · Journey C2 |
| Dashboard tiles & fleet services | Dashboard & Services |
| Backup / patch / LAN / Docker / console history (not Grafana) | Reports |
Backups & patching¶
| Scenario | Doc |
|---|---|
| Configure rsync sources + schedule | Backups |
| Restore path (dry-run then apply) | Backups |
| Check OS / images only | Updates |
| Apply OS or container patch | Updates |
| Bulk check/patch/backup many hosts | Updates — Bulk |
| Reboot without hanging the UI | Updates — Reboot |
| See job progress / cancel | Jobs |
| Who did what (incl. client IP) | Audit |
Docker on hosts¶
| Scenario | Doc |
|---|---|
| Browse projects / containers / logs | Docker overview |
| Stop / Start / Restart all services in a project | Docker overview — lifecycle |
| Move a compose project to another host | Move a service · Journey Move |
| Split services across compose files (same folder) | Compose sets · Compose edit |
| Runtime stack view groups on the map | Network — view groups |
| First cert → map / Apply to this PiHerder | Managed certificates · Trusted HTTPS |
| Fast open via inventory cache | Inventory |
| Edit compose, validate, deploy version | Compose edit |
| Stack Check updates vs Deploy | Updates — Docker |
| Prune dangling images / exited containers | Docker overview |
Integrations & discovery¶
| Scenario | Doc |
|---|---|
| Opt-in LAN nmap (worker, devices, schedules) | LAN Discovery · Journey H |
| Network maps (DNS / topology) | Network maps |
| Stale Jobs / Audit / nmap-run purge | Settings — cleanup |
Service templates¶
| Scenario | Doc |
|---|---|
| Catalog badges OOTB vs Yours | Templates overview |
| Deploy OOTB NPM / Kuma / Pi-hole / Grafana | Deploy · Journey D |
| Redeploy, volumes, wait modal | Deploy — Redeploy |
Check drift / Accept host as desired / import host .env / apply last known | Deploy — ops |
| Pull existing stack + sidecar configs (promtail, etc.) | From host · Journey D2 |
| View secrets (step-up 2FA) | Secrets |
Catalog: integrations & network¶
| Scenario | Doc |
|---|---|
| Catalog tabs (Integrations / Certificates / Templates / Network) | Integrations overview |
| Connect Kuma + bind services | Uptime Kuma |
| Grafana deep links + preferred names | Grafana |
| Multi Pi-hole, DNS fan-out, gravity | Pi-hole |
| Host A records, service paths, Hosts/Path maps, runtime stack expand + container order | Network maps |
| Switch light/dark; ops-hero layout | Appearance |
| NPM proxy hosts (read-only) + pull cert | NPM |
| Cert vault, maps, deploy, renew | Certificates |
Account, users, security¶
| Scenario | Doc |
|---|---|
| Viewer / operator / admin | Roles |
| Create users, roles | Users |
| TOTP, passkeys, backup codes, force 2FA | 2FA |
| SSO / OpenID Connect | SSO |
| In-browser SSH (flag off by default) | Web SSH console |
| Install PWA + Web Push | PWA & push |
Operations & DR¶
| Scenario | Doc |
|---|---|
.env keys | Env reference |
| Volume mounts | Volumes |
| Settings tabs (backup, security, Alerts, status, timezone, API) | Settings |
| Stack Status healthy? | Status |
| Herder self-backup / restore (admin only) | Self-backup · Roles |
| Upgrade compose / image | Upgrades |
| v1.2 freeze QA / sign-off | QA checklist (historical Hub 1.2) |
| More backup parallelism | Multi-worker |
| Prometheus / env webhook fallback | Metrics |
| Webhook + SMTP alerts / forgot password | Alerts |
| Token REST for n8n/HA | API tokens |
| Generic HA / Frigate / n8n links | Generic links |
When things go wrong¶
| Scenario | Doc |
|---|---|
| SSH / rsync / docker group / host-key pin | SSH troubleshooting |
| Backup stuck | Backup troubleshooting |
| Push not arriving | Push troubleshooting |
| Template / compose editor | Templates troubleshooting |
| Symptom table | Troubleshooting index |