Ops-dashboard/docs/handleiding.md
Janpeter Visser fda7be3214 docs: handleiding + functionele + technische specificatie
Drie nieuwe markdown-bestanden onder /docs:

- handleiding.md — voor de dagelijkse gebruiker: eerste login, modules,
  veelvoorkomende taken (Caddy editen, sprint mergen via flow), wat
  expliciet niet vanuit de UI kan, log-locaties bij incidenten,
  veiligheidsadvies.

- specs/functional.md — wat de app doet: scope per module met
  acceptatiecriteria, flow state-machine (pending/running/success/
  failed/cancelled/timeout), hard limits (1 actieve flow, 64KB log
  knippen, 24u session), expliciete buiten-scope-lijst.

- specs/technical.md — hoe het werkt: 3-process architectuur
  (dashboard container + agent op host + Postgres), stack-tabel met
  versies en redenen, data-model (User/Session/FlowRun/FlowStep),
  auth-flow met CSRF, agent-protocol over SSE, security-eigenschappen
  per laag.

Lengtes pragmatisch gekozen — geen completeness-fetisj, wel genoeg
om iemand die nieuw is in de codebase binnen 30 min te oriënteren.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:35:49 +02:00

5.8 KiB

Handleiding — Ops Dashboard

Voor de dagelijkse beheerder van een single-host server-stack (Docker, systemd, Git, Caddy, Postgres). Deze handleiding beschrijft hoe je de app gebruikt, niet hoe hij werkt — voor dat laatste zie specs/technical.md.

Eerste inlog

  1. Open https://<jouw-host>/ (bv. https://ops.jp-visser.nl).
  2. Je wordt doorgestuurd naar /login. Vul de admin-credentials in die je tijdens deploy in SEED_USER_EMAIL / SEED_USER_PASSWORD hebt gezet.
  3. Na succesvolle login zit je 24 uur ingelogd via een HttpOnly-cookie. Daarna opnieuw inloggen.

Wachtwoord vergeten? Geen reset-flow in de app — los op met een SQL-update:

# Genereer een nieuwe bcrypt-hash voor je nieuwe wachtwoord
docker run --rm -e PW='<nieuw-wachtwoord>' node:22-alpine sh -c '
  cd /tmp && npm init -y >/dev/null 2>&1 && npm install --silent bcryptjs >/dev/null 2>&1
  node -e "console.log(require(\"bcryptjs\").hashSync(process.env.PW, 12))"
'
# Plak in psql:
docker exec -it scrum4me-postgres psql -U scrum4me -d ops_dashboard \
  -c "UPDATE \"User\" SET pwd_hash = '<hash>' WHERE email = '<jouw-email>';"

Dashboard (home)

Vijf live status-widgets, auto-refresh ~5 sec:

Widget Toont
Docker Aantal draaiende containers + lijst
Git Branch en uncommitted-status per geconfigureerd repo-pad
systemd Service-status (active/inactive/failed) per geconfigureerde unit
Caddy TLS-certs met dichtstbijzijnde expiratiedatum (geel = <30 dagen)
Audit Laatste flow-run met timestamp en exit-status

Klik een widget aan om naar de detail-pagina te gaan.

Modules

/docker — Containers

Tabel van docker ps met auto-refresh. Klik op een container-naam voor detail (logs, image, ports, status).

Read-only — geen start/stop/restart vanuit de UI. Voor wijzigingen: een Flow (zie hieronder).

/git — Repositories

Per geconfigureerd pad in REPO_PATHS (env var): branch, uncommitted-files (M/A/D/??), laatste 3 commits. Klik door voor diff-viewer.

Read-only — pulls/commits gaan via een Flow.

/systemd — Services

Lijst van services uit SYSTEMD_UNITS (env var). Toont status, laatste log-regels. Klik door voor full journal-tail van die unit.

Restart-knop: alleen voor units die in commands.yml zijn whitelisted én in sudoers.d/ops-agent met NOPASSWD staan.

/caddy — Reverse-proxy & TLS

Toont de actieve Caddyfile (syntax-highlighted) plus alle TLS-certs (subject + expiry). "Edit"-knop opent een editor — opslaan valideert de Caddyfile via caddy validate voordat het wordt geschreven.

/flows — Multi-step deployments

Twee voor-gedefinieerde flows:

  • Update Scrum4Me website — pull main, build container, restart, smoke-test
  • Update Caddy config — schrijf nieuwe Caddyfile, valideer, restart Caddy, verifieer dat alle hostnames nog reageren

Een flow draait stap-voor-stap met dry-run als standaard. Na dry-run zie je per stap wat het gaat doen. Klik "Run" om echt uit te voeren. Tijdens executie zie je live stdout/stderr per stap.

/audit — Flow-runs

Chronologische lijst van alle gestarte flows: starttijd, duur, exit-status, wie 'm startte. Klik door voor de volledige output (stdout/stderr per stap).

/settings/backups — Backups

Postgres backup-management:

  • Lijst van bestaande dump-bestanden in /srv/scrum4me/backups
  • "Backup now"-knop maakt een dump met timestamp-naam
  • Restore-runbook (handmatige stappen — geen automatische restore vanuit UI om de blast-radius klein te houden)

Veelvoorkomende taken

Container hangt — wat nu?

  1. /docker → klik container-naam → bekijk logs
  2. Diagnose? Open een SSH-sessie en gebruik docker logs, docker exec etc. (Niet vanuit de UI — dat is buiten scope.)
  3. Restart nodig? Voeg de container toe aan commands.yml whitelist (op de host) + run via /flows

Caddy-config wijzigen

  1. /caddy → "Edit"
  2. Pas Caddyfile aan in de editor
  3. Save → app draait caddy validate → bij succes wordt het geschreven en Caddy herstart
  4. Verifieer in /caddy dat het cert-overzicht klopt

Voor breaking changes (verkeerde syntax of niet-bestaande site): de validate-stap blokkeert. Bij twijfel: maak eerst een backup van /srv/scrum4me/caddy/Caddyfile.

Sprint mergen via flow

/flows/update-scrum4me-web — kies branch (default main), klik dry-run, lees wat het doet, klik "Run". Stap-output stream live. Na success: smoke-test verifieert dat de homepage 200 geeft.

Wat kan niet vanuit de UI

  • SSH-toegang of arbitrary shell-commando's (alleen whitelisted commands.yml-keys)
  • User-management (één admin via seed; multi-user is buiten scope)
  • Container starten met andere image of args (alleen restart van bestaande)
  • Wachtwoord reset (SQL-update vereist)
  • Cert handmatig forceren (Caddy doet auto-ACME)

Logs voor incident-response

Component Log-locatie
Dashboard app docker logs scrum4me-ops-dashboard
ops-agent journalctl -u ops-agent -f
Caddy docker logs scrum4me-caddy
Postgres docker logs scrum4me-postgres

Audit-trail van wat-doet-wie-wanneer: tabel FlowRun + FlowStep in de ops_dashboard database, of via /audit in de UI.

Veiligheidsadvies

  • Houd port 3099 (ops-agent) niet open naar de buitenwereld. UFW-regel scoped op 172.18.0.0/16. Zie runbooks/post-install.md.
  • Roteer OPS_AGENT_SECRET jaarlijks: nieuw secret in .env én /etc/ops-agent/secret, dan beide herstarten.
  • Voeg geen wildcards toe in sudoers.d/ops-agent — elke systemctl-actie moet een expliciete service-naam zijn.
  • commands.yml is single source of truth voor wat de agent mag — alles wat niet in de whitelist staat, kan een aanvaller niet uitvoeren ook al heeft hij het secret.