Demo mode
Demo mode seeds a self-contained showcase environment into the default tenant so you can click through a populated instance: real built-in checks against loopback and public targets, a passive job with a heartbeat, the full notification/escalation/on-call stack, a business-service tree with an SLA, a dashboard, a scheduled report, inbound event sources, a recurring downtime and two demo users. Seeding only writes configuration — the scheduler and executor then run the checks live.
Enabling it
Section titled “Enabling it”| How | Behaviour |
|---|---|
northplaned serve --demo |
seeds unconditionally on every start (idempotent). Optional flags: --demo-snmp host:161 (target of the SNMP demo checks, default 127.0.0.1:161) and --demo-traps udp://:9162 (listen address of the demo SNMP-trap source). This is what make dev and the e2e suite use. |
demo: true in config.yaml or NORTHPLANE_DEMO=true |
seeds on start, but only after the real-data guard passes (below). This is the demo/real switch of the production stacks. |
Seeding runs before the HTTP listener comes up; a failure is fatal (demo seed: …). The log
reports what happened:
demo: user ready name=demo-operator [email protected] password=operator-demo-2026! role=operatordemo: user ready name=demo-viewer [email protected] password=viewer-demo-2026! role=viewerdemo: hint msg="passive service demo-batchjob & heartbeat demo-cron have no live feeder — …"demo: hint msg="channel demo-email points at a mock SMTP sink on 127.0.0.1:2525 and demo-hook at http://127.0.0.1:18081/hook — …"demo: hint msg="event-source demo-hook-in uses authMode=token with secretRef \"demo-hook-in-token\" — …"demo: environment seeded counts=map[alert-rule:2 business-service:4 channel:2 …]Demo users
Section titled “Demo users”| Login | Password | Role | Can |
|---|---|---|---|
[email protected] (name demo-operator) |
operator-demo-2026! |
operator |
read everything, create and edit hosts/services, ack/resolve/raise alerts, incidents, downtimes, silences, on-call, dashboards, reports — but no Admin tabs and no config documents (templates, rules, channels need config:write). |
[email protected] (name demo-viewer) |
viewer-demo-2026! |
viewer |
read only. |
The demo does not create an administrator. The admin is the break-glass account that
northplaned serve seeds on every start unless NP_DEFAULT_ADMIN_DISABLED is set
(admin@localhost with a generated password in the log, or NP_DEFAULT_ADMIN_EMAIL /
NP_DEFAULT_ADMIN_PASSWORD) — see the Quickstart.
What is seeded
Section titled “What is seeded”Every artefact is named demo-…, labelled demo=true, and lives in the default tenant.
| Kind | Names and key settings |
|---|---|
| Templates | demo-host-base (host: interval 30 s, retry 10 s, 2 attempts, timeout 10 s), demo-web-service (service: 60 s, timeout 10 s) |
Hosts (folder /demo) |
demo-gateway (127.0.0.1, builtin:icmp, 15 s; labels role=gateway, site=demo); demo-web (builtin:https against https://example.org, parent demo-gateway, template demo-host-base); demo-dns (builtin:dns -H example.org, parent demo-gateway); demo-snmp-device (builtin:snmp sysUpTime against the --demo-snmp target, 30 s) |
| Services | demo-snmp-ifwalk (snmp-walk ifOperStatus, 60 s) and demo-tls (tls-cert example.org:443 -w 21 -c 7, every 6 h) on demo-snmp-device; demo-web-latency (https -w 1.0 -c 3.0, 30 s) on demo-web; demo-batchjob (passive, stalenessAfter 10 m, contact group demo-ops, notifyOn critical+recovery) on demo-gateway |
| Heartbeat | demo-cron — expect every 5 m, grace 1 m, severity warning |
| Contacts, group | demo-alice ([email protected], e-mail), demo-bob ([email protected], webhook + e-mail), group demo-ops |
| Channels | demo-email (SMTP 127.0.0.1:2525, from [email protected], allowPlaintext), demo-hook (webhook http://127.0.0.1:18081/hook) |
| Alert group | demo-storm (group by host, 5 m window, min count 3) |
| Escalation policy | demo-escalation: step 0 → demo-ops by e-mail; +15 m unless acked → demo-bob by webhook |
| Alert rules | demo-critical (CEL: hard state_change to CRITICAL/DOWN; severity critical; title demo: {{ .event.object }} is {{ .event.state }}; policy demo-escalation; group demo-storm; sets label demo=true), demo-heartbeat-rule (heartbeat rule on demo-cron, every 5 m, warning) |
| On-call schedule | demo-oncall (Europe/Vienna; layer primary, weekly alice → bob, anchored Monday 2026-01-05 08:00) |
| Business services | root demo-webshop (rule worst, SLA 99.9 % monthly) with leaves demo-webshop-web, demo-webshop-dns, demo-webshop-gateway bound by selectors such as role=web,demo=true |
| Dashboard | demo-overview (shared): counters, problems, metric chart of demo-web-latency (time, 3 h), BPI demo-webshop, table with selector demo=true |
| Report | demo-availability: availability over 30 days for demo=true, folder /demo, schedule daily@07:00, e-mailed to alice, keep 7 |
| Event sources | demo-hook-in (webhook, token auth, secretRef: demo-hook-in-token), demo-traps (SNMP trap listener on the --demo-traps address, community public, severity warning), demo-imap (IMAP 127.0.0.1:3143, disabled) |
| Downtime | demo-batchjob-nightly: fixed, next 03:00 Europe/Vienna for 1 h, RRULE FREQ=DAILY;BYHOUR=3;BYMINUTE=0 |
| Users | demo-operator, demo-viewer (above) |
What you will see after a minute: demo-gateway UP (if ICMP works for the server’s user),
demo-web, demo-dns, demo-tls and demo-web-latency OK when the host has internet access,
the SNMP objects CRITICAL/UNKNOWN unless --demo-snmp points at a reachable SNMP agent,
demo-batchjob turning UNKNOWN (stale) after 10 minutes, and the demo-cron heartbeat reported
missing right away — which opens a warning alert through demo-heartbeat-rule, so the alarm
pipeline has something to show.
Parts that need a helping hand
Section titled “Parts that need a helping hand”The seeder writes configuration only; a few pieces point at infrastructure it does not start:
demo-emailanddemo-hookdeliver to a mock SMTP sink on127.0.0.1:2525and a webhook sink on127.0.0.1:18081. Nothing listens there by default, so their deliveries fail, retry with backoff and end up under Admin → Dead letters — a realistic demonstration of the outbox, but run a sink (any SMTP test server, any HTTP echo) on those ports if you want green deliveries.demo-hook-inauthenticates inbound webhooks with the secretdemo-hook-in-token, which is not created. Store it (PUT /api/v1/secrets/demo-hook-in-token, or Admin → Secrets) and thenPOST /api/v1/ingest/demo-hook-inwithAuthorization: Bearer <that value>.demo-batchjobanddemo-cronhave no feeder. Submit a result (POST /api/v1/resultswith{"results":[{"host":"demo-gateway","service":"demo-batchjob","state":0,"output":"batch ok"}]}) and beat the heartbeat (POST /api/v1/heartbeats/demo-cron/beat), both with a token holdingobjects:write, to watch them recover. (The log hint names/checks/results; the real path is/api/v1/results.)- The SNMP demo wants an SNMP agent:
--demo-snmp 10.0.0.1:161targets a real device with communitypublic; traps sent to the--demo-trapsport (9162/udp, publish it in Docker) show up as events.
Idempotency and the real-data guard
Section titled “Idempotency and the real-data guard”- Idempotent. Re-running the seed updates in place: configuration resources are upserted by
name, objects are matched by kind, host and name, and ids are derived deterministically from the
names (SHA-256-based, UUID-shaped), so cross-references such as BPI parents stay valid. Existing
demo users are reported again instead of failing. You can leave
--demoon permanently. - Guarded. With
demo: true/NORTHPLANE_DEMO=truethe server first checks whether the default tenant already contains any host without the labeldemo=true(up to 5000 hosts; a query error counts as “real data”). If so it logsNORTHPLANE_DEMO is set but this database already holds real (non-demo) hosts — skipping demo seeding to protect production data; use a dedicated data dir/volume for the demo, or unset NORTHPLANE_DEMOand starts without seeding. The explicit--demoflag bypasses the guard — do not use it on a production data directory. - No teardown command. Demo artefacts are easy to find (label
demo=true, prefixdemo-, the Objects page filterdemo=true), but the clean way to get rid of them is the one the production stacks use: a separate data directory you can delete.
Demo and real data directories in the production stack
Section titled “Demo and real data directories in the production stack”The CI-managed stacks under deploy/ treat NORTHPLANE_DEMO as a switch that also selects the data
directory inside the same volume:
NORTHPLANE_DEMO=trueNORTHPLANE_DATA_DIR=/var/lib/northplane/demo # false → /var/lib/northplane/realDemo mode uses /var/lib/northplane/demo, real mode /var/lib/northplane/real, so flipping the
switch never mixes the datasets and each side keeps its own database, events, TSDB and
secret.key. The GitHub variable NORTHPLANE_DEMO (and the demo dropdown of the manual Deploy
run: repo-default / true / false) controls it; the public showcase instance has run in real
mode since 2026-08-20 with its demo directory kept alongside. Details:
CI/CD and Operations.
For a hand-run container the same idea is -e NORTHPLANE_DEMO=true -e NORTHPLANE_DATA_DIR=/var/lib/northplane/demo,
or simply a second named volume.
Development and tests use it too
Section titled “Development and tests use it too”make devstarts the backend with-demo(setNP_DEV_DEMO=0to skip) and prints the demo credentials; the generated break-glass admin password appears in the[api]log lines.- The Playwright end-to-end suite (
make e2e) boots an isolatednorthplaned serve --demowithNP_DEFAULT_ADMIN_DISABLED=1, mints a token withbootstrap-admin, creates its own admin throughPOST /api/v1/users, and pins the browser locale tode-DE— so the demo data is what the e2e tests click through (Testing). - The CI
e2ejob does the same against every commit.
Related
Section titled “Related”- Quickstart and First steps
- Configuration — the
demokey andNORTHPLANE_DEMO - CLI: northplaned —
serve --demo,--demo-snmp,--demo-traps - Storage — data directory layout and backups