Live infrastructure overview · Noaber.ai

De volledige stack,
in één oogopslag.

Alles wat draait, waar het draait, en waar het wringt. Bedoeld als single source of truth voor cross-asset besluitvorming, recovery-planning en migratie-prioriteiten.

laatst bijgewerkt 10/10 backups OK · 0 SPOFs v6 · 2026-07-02 · MacBook Pro M5 Max toegevoegd als primary werkstation (48 GB, Ollama lokaal); M4 nu reserve
23
CF zones
helsdingen, michelmedia, noaber.ai, klant-domeinen
10
CF Pages
portfolio, klant-portalen, dashboards
20
CF Workers
backup-collectors, klant-apps, API's, dekei1
47
Containers (plex)
Coolify-stack + losse services
11TB
Synology storage
4.1 TB used · 6.4 TB free
10
Hosts in beheer
2 VPS · 1 Proxmox · 1 NAS · 1 Mac mini · 2 MBP (M5 Max + M4) · 2 Win · Homey
46d
Plex uptime
~14d Proxmox · 14d Synology · live 2026-07-13
512MB
claude-mem.db
jouw werkgeheugen — irreplaceable
0
SPOFs over
Vaultwarden + Paperless beide gemitigeerd met daily encrypted R2 backup (mei 2026)
Rapporten & analyses

Alle losse deliverables in deze map, nieuwste eerst. De vier vaste documenten (Discovery, Migration, Failover, Rebrand) staan in de navigatie hierboven. Nieuw rapport erbij? Zet hem hier meteen neer, anders raakt hij zoek.

Backups

Alle backup-lagen in een oogopslag. Vier betalende klanten draaien elk drie lagen: een Cloudflare-cron (D1 naar R2), een onafhankelijke off-site pull op de NUC die de restore decrypt-verifieert, plus een wekelijkse restore-drill die de off-site dump écht terugzet in een verse SQLite-db. Eigen systemen vullen het 3-2-1 plaatje aan. Status gespiegeld van de collector op backup.noaber.ai.

16systemen OK
0failed
0missing
5off-site geverifieerd
4restore-drills
laatste sync 2026-05-30 · bron backup.noaber.ai
TopView betalend · 3 lagen
topview-backup
cf-cron · D1 -> R2
OK vannacht 02:00 UTC
topview-offsite
offsite · NUC-pull3-2-1 off-site geverifieerd
OK dagelijks 04:00 · decrypt-geverifieerd
topview-restoredrill
restore-drill · wekelijksterugzet bewezen
OK zondag 05:30 · kern-rows geteld
Lurvink KMS betalend · 3 lagen
lurvink-kms-backup
cf-cron · D1 -> R2
OK vannacht 02:00 UTC
lurvink-offsite
offsite · NUC-pull3-2-1 off-site geverifieerd
OK dagelijks 04:00 · decrypt-geverifieerd
lurvink-restoredrill
restore-drill · wekelijksterugzet bewezen
OK zondag 05:30 · kern-rows geteld
BubbelBal betalend · 3 lagen
bubbelbrein
cf-cron · D1 -> R2
OK vannacht 02:00 UTC
bubbelbrein-offsite
offsite · NUC-pull3-2-1 off-site geverifieerd
OK dagelijks 04:00 · decrypt-geverifieerd
bubbelbrein-restoredrill
restore-drill · wekelijksterugzet bewezen
OK zondag 05:30 · kern-rows geteld
Te Kloeze betalend · 3 lagen
tekloeze-rapportage-backup
cf-cron · D1 -> R2
OK vannacht 02:00 UTC
tekloeze-rapportage-offsite
offsite · NUC-pull3-2-1 off-site geverifieerd
OK dagelijks 04:00 · decrypt-geverifieerd
tekloeze-rapportage-restoredrill
restore-drill · wekelijksterugzet bewezen
OK zondag 05:30 · kern-rows geteld
Eigen systemen noaber · 3-2-1
paperless-r2
plex bash · tar -> GPG -> R2
OK vannacht 04:15
restic-mbp-mini
launchd · MBP -> Mac mini SFTP
OK vannacht 03:30
restic-mbp-r2
launchd weekly · MBP -> R2 offsite3-2-1 off-site geverifieerd
OK zo 04:00 · 4 dgn geleden
vaultwarden-r2
launchd · encrypted_json -> R2
OK vannacht 02:30
Network topology

Hoe de drie lagen samenhangen. Cloudflare orchestreert al het verkeer; tunnels exposen lokale services veilig publiek; werk-VPS is dik maar afhankelijk.

graph TB
  classDef cloud fill:#1a1530,stroke:#a78bfa,stroke-width:2px,color:#e9d5ff
  classDef vps fill:#2a1a10,stroke:#f59e0b,stroke-width:2px,color:#fde68a
  classDef home fill:#0f1f1a,stroke:#10b981,stroke-width:2px,color:#a7f3d0
  classDef warn fill:#2a1010,stroke:#ef4444,stroke-width:2px,color:#fecaca
  classDef neutral fill:#161620,stroke:#6b6b76,stroke-width:1px,color:#a1a1aa

  subgraph CLOUD["☁️  Cloud · Managed"]
    CF["Cloudflare
26 zones · 10 Pages · 20 R2 · 22 D1 · 30 Workers"] M365["Microsoft 365
info@ · scan@"] MB["Moneybird"] GH["GitHub"] APPLE["Apple Developer"] end subgraph VPS["🖥 VPS · werk-eigendom"] PLEX["plex.helsdingen.com
37.97.202.216
50 containers"] DJEFF["djeffrey
37.97.148.97
Plesk · padelclippy.nl"] end subgraph HOME["🏠 Thuis-netwerk · 192.168.2.0/24"] MBP["MacBook Pro M5 Max
primary · 48 GB · 26.5.1"] M4RES["MacBook Pro M4
reserve · .17"] MINI["Mac mini
.154 · M4 Pro 24 GB · 26.x arm64"] NUC["NUC Proxmox
.100 · PVE 9.1.1"] NAS["TeRRoR Synology
DS916+ · DSM 7.2"] RTX["Dikke3090
.142 · RTX 3090"] HOMEY["Homey Pro 2023
.176"] end subgraph PROX["⚙️ Proxmox subgrid"] CAMS["LXC 102 · cams
.228 · CamViewer"] TOPV["LXC 103 · topview-backup
.145"] CFLT["LXC 101 · cloudflared
.148"] HAOS["VM 100 · Home Assistant
4 GB RAM"] end CF -.->|tunnel b88e…| PLEX CF -.->|tunnel 1931…| CFLT CFLT --> HAOS CFLT --> NAS NUC --> CAMS NUC --> TOPV NUC --> CFLT NUC --> HAOS GH -->|code| MBP GH -->|code| MINI CF -->|DNS edge| MBP M365 -.- MBP MBP <==>|"Syncthing two-way
~/.claude only"| MINI MBP ==>|"restic nightly 03:30
SFTP · hele ~/Documents · ~15 GB"| MINI MBP ==>|"restic weekly zo 04:00
S3 R2 · hele ~/Documents · offsite"| CF PLEX ==>|"Vaultwarden daily 02:30
encrypted_json → R2 + lokaal"| CF class CF,M365,MB,GH,APPLE cloud class PLEX,DJEFF vps class MBP,M4RES,MINI,NUC,NAS,RTX,HOMEY home class CAMS,TOPV,CFLT,HAOS neutral
SafeEigen, redundant of vervangbaar zonder bedrijfsrisico
Managed cloudExterne leverancier, betaald, vendor-redundancy
DependentWerkgever-eigendom, gratis nu — strategisch risico
SPOFSingle point of failure — outage = direct bedrijfsstilstand
UnderusedAanwezig maar onderbenut — kandidaat voor herrol
Cloud · managed laag

Externe SaaS waar Michel betaalt of gratis-tier op leunt. Vendor zorgt voor redundancy. Risico = vendor-lockin + accountverlies.

Cloudflare
michel@helsdingen.com · acct 91a07c8e…
managed

Het zenuwstelsel. DNS, TLS, edge-routing, WAF, tunnels, Pages, Workers, R2, D1, Custom Hostnames. Alles tussen klant en service loopt hier doorheen.

Zones24 actief
Workers25 live
R2 buckets19 (incl. backup-buckets)
D1 databases17
Tunnels2 actief
AuthUser API Token (wrangler)
Pages Workers R2 D1 Tunnels Custom Hostnames Access
Microsoft 365
michelmedia.nl · Exchange Online
managed

Zakelijke e-mail. info@ + scan@ shared mailbox. scan@ voert Paperless via mail-fetcher v2.

Mailboxesinfo@ shared
Forwardscan@ alias
SMTPMicrosoft
Backupvendor
Exchange Graph API
Moneybird
admin 484693210194510890
managed

Administratie single source of truth per 1-7-2026. Facturen al actief verstuurd via REST API: QuickSlide 2026-0002 (€2.400) + 2026-0003. 2 recurring (Lurvink + QS) live, eerste cyclus 1-6 (auto_send uit voor handmatige juni-review). Inkoopbonnen lopend (o.a. NextDNS, KPN 15-05). KvK-nr invullen na KvK-afspraak 19-05. KOR 0% BTW tot 30-6-2026.

StatusActief · facturen verstuurd
APIREST v2 · Bearer
RecurringLurvink + QS · start 1-6
KOR0% tot 30-6-2026
Backupvendor
REST API MCP optie
GitHub
michelhelsdingen / private repos
managed

Code SSOT. Alle klant-projecten en eigen tools. Migratie zou triviaal zijn (clone + push elders), dus laag risico.

Code Issues Actions
Apple Developer
Team 58PR8DAVZM · Individual
managed

Voor PadelClippy + CashSpot iOS. App Store Connect, push keys, signing certs.

App Store TestFlight Push
Sentry · TelemetryDeck · NVIDIA
monitoring + analytics + AI API
managed

Crash reporting (Sentry), usage analytics (TelemetryDeck), Llama-Nemotron API (gratis). Niet bedrijfskritiek — observability/experimenten.

Sentry TelemetryDeck NVIDIA
Supabase hosted
Frankfurt · 2 free-tier projecten
managed

LTC Event Planner + LTC Padel Planning. Free-tier — pauzeert na 7d inactiviteit, keep-alive cron via launch-agent.

Postgres Auth REST
VPS · werk-eigendom

Twee TransIP VPSen, beide via werkgever (Gemeente Oost Gelre) gratis beschikbaar. Je betaalt niets, maar je bezit ze ook niet — strategisch belangrijke nuance.

plex VPS
37.97.202.216 · plex.helsdingen.com · Ubuntu
werk · dik

De monoliet. 50 containers, 6 TB media, 700 GB Docker volume, 96 GB root. Coolify orchestreert alles. Draait 46 dagen. Te zwaar geladen voor één host die je niet bezit.

Root96 GB · 24% used
Docker700 GB · 24% used
Media6 TB · 47% used
Uptime46 dagen (2026-07-13)
Vaultwarden Paperless Coolify Supabase Immich Jellyfin Uptime Kuma n8n Portainer Watchtower Homepage Glances Happy server Cloudflared change-detection AI-news-bot MEXC bot
Vaultwarden (op plex)
vault.helsdingen.com · CF Access
MITIGATED

Bron-of-truth voor alle credentials, klanten, recovery. Plex-uitval is geen lockout meer: daily encrypted export beschikbaar via R2 + lokaal.

credentials daily R2 backup 3-layer encryption
Paperless-ngx (op plex)
docs.helsdingen.com · CF Access
MITIGATED

Alle Belastingdienst-relevante documenten (7 jaar bewaarplicht). 5 containers (web, redis, gotenberg, tika, mail-fetcher). Plex-uitval is geen verlies meer: 3 onafhankelijke backup-lagen.

7 jaar bewaarplicht backup lokaal NAS Tailscale sync daily R2 backup GPG AES256
djeffrey VPS
37.97.148.97 · Plesk Obsidian
werk · web+mail

PadelClippy.nl/.com hosting + SMTP relay. Ubuntu 24.04, Plesk-managed. Onafhankelijk van plex, eigen Cloudflare Origin Cert tot 2041.

Webpadelclippy.nl/.com
SMTPmail.padelclippy.nl:587
CertCF Origin · 2041
SSHport 2222
Plesk SMTP
Thuis-netwerk · eigen hardware

Wat hier draait, bezit je. Stroom kost iets, verder niets. Onderbenutting is hier de hoofdkans, niet capaciteit.

MacBook Pro M5 Max
m5maxmichel.local · macOS 26.5.1 · TS 100.87.252.68
primary

Nieuw primary werkstation sinds ~22-06-2026 (verving de M4 als dagelijkse machine; M4 nu reserve). Apple M5 Max, 18 cores, 48 GB, 2 TB. Alle klantwerk, deploys, schrijven, plus lokale LLM-inferentie voor development. ~/.claude (3.0 GB) + claude-mem.db (512 MB) = jouw werkgeheugen. Backup-strategie draait hier: nightly restic naar Mac mini (SFTP, lokaal) + weekly restic naar Cloudflare R2 (offsite, EU), volledige ~/Documents. Beide jobs rapporteren centraal naar backup.noaber.ai; 1 geconsolideerd Telegram-bericht om 06:00. Syncthing houdt ~/.claude live gesynct.

Chip · RAMApple M5 Max · 18 cores · 48 GB (Mac17,6)
Storage2 TB · 1,4 TB vrij (1% gebruikt)
Lokale LLMOllama :11434 · qwen3-coder:30b, devstral:24b, qwen3.5-abliterated:27b, llama3.2:3b
Local backupTime Machine (lokaal)
Backup primaryrestic → Mac mini SFTP nightly · hele ~/Documents
Backup secondaryrestic → R2 offsite weekly · hele ~/Documents
Monitoringbackup.noaber.ai · 06:00 geconsolideerd
Live syncSyncthing ~/.claude → Mac mini
Claude Code Codex OpenCode + lokale modellen Ollama Xcode Vaultwarden CLI Syncthing restic · dual repo tooling-review (launchd)
MacBook Pro M4
m4promichel.local · TS 100.76.162.47
reserve

Voormalig primary, sinds ~22-06-2026 reserve/secundair werkstation na overstap naar de M5 Max. Blijft ingericht en inzetbaar als volwaardige terugval; klantwerk en tooling staan er nog op. Bedraad 2.5G via USB-adapter (en11, 192.168.2.17).

Rolreserve werkstation / tweede machine
NetwerkLAN 192.168.2.17 (2.5G) · Tailscale 100.76.162.47
Claude Code Xcode reserve/failover
Mac mini
192.168.2.154 · macOS 26.4 arm64 · M4 Pro 24 GB
hot standby

M4 Pro 24 GB, 12 cores. Primary backup target. Host van restic SFTP-repo voor nightly encrypted backups van MBP — sinds 2026-05-15 inclusief de volledige ~/Documents (~31 GB snapshot → ~15 GB stored). Ontvangt ook Syncthing-sync van ~/.claude (claude-config). Bij MBP-uitval: open Mac mini, restic-restore vanaf SFTP-repo, ga door binnen 10 min. Documents-sync was geschrapt 2026-05-10 (case-conflicts, restic dekt het af).

Storage460 GB · 142 GB free
Restic repo~/restic-backups/main · 10 snapshots
Repo size~21 GB op disk (hele ~/Documents incl.)
Last snapshot2026-05-15 17:38 (hele ~/Documents)
Syncthing target~/.claude · 13037 files
Mail-assistentlaunchd ai.noaber.mailsignal · info@vakwark.ai (alle noaber.ai- en michelmedia.nl-adressen als alias) · elke 3min · lokale Ollama (qwen3.6-genesis) → actie-to-do per project + Telegram. Autonoom inkoopfacturen boeken (mb_invoice: PDF uit Paperless → MB, dedup+verificatie, betaalt nooit). Sinds 04/05-06-2026.
Syncthing v2.0.16 restic SFTP target Docker.app (idle) Ollama (mail-analyse) mail-signal (launchd 3min) auto inkoopfactuur→MB Happy CLI Postgres@14/17
NUC · Proxmox
192.168.2.100 · PVE 9.1.1 · 88d up
stabiel

Hosting platform thuis. Draait CamViewer, TopView/QuickSlide zinker en Home Assistant. Veel ruimte voor extra LXCs (Vaultwarden mirror, Paperless mirror, Lurvink staging).

LXC 101cloudflared (.148)
LXC 102cams (.228)
LXC 103topview-backup (.145)
VM 100haos12.4 · 4 GB
CamViewer TopView zinker Home Assistant cloudflared tunnel
TeRRoR · Synology
DS916+ · DSM 7.2.0 · 142d up
underused

11 TB volume, 6.4 TB ongebruikt. Doet nu vooral Surveillance Station camerabeelden. Heeft ContainerManager, Node.js v16/18/20, CloudSync, Replication. Klaar om backup-target voor alles te worden.

Volume11 TB · 4.1 TB used
Free6.4 TB · 60% open
Dockerja (CM)
TailscaleSSH key gereed
Surveillance ContainerManager CloudSync Replication
Dikke3090
192.168.2.142 · Win11 · RTX 3090 24GB
on demand

ComfyUI op poort 8188. Lokale GPU-zware workflows: image gen, eventueel lokale LLMs. ~120 custom nodes geïnstalleerd.

ComfyUI RTX 3090 i9-11900K
Oude MacBook Pro
slaapt · macOS
unused

Doet nu niets. Voorgestelde rol: clean reference machine met maandelijkse image refresh, of cold standby met bootstrap-script. Geen sync nodig — alleen restorable basis.

cold standby
Homey Pro 2023
192.168.2.176 · firmware 13.1.2
smart home

Smart home hub. Eigen Tuya Local app v0.6.2 draait. Niet bedrijfskritiek maar wel persoonlijk waardevol.

Z-Wave Zigbee Tuya Local
Cam PC Kantoor
192.168.2.66 · Surface Win11
camera

Camera PC voor kantoor-monitoring. Beperkte rechten, alleen view. Niet voor zakelijke compute-taken.

cam viewer
Service-mapping · waar draait wat

Per service: huidige host, welke kolom moet veranderen in de eindsituatie. Sweet-spot voorstel.

ServiceNuSweet spotWaarom
Vaultwardenplex.helsdingen.comNUC LXC + R2 export SPOF wegnemen — credentials moeten op eigen hardware
Paperless-ngxplex + R2 backupMac mini Docker (lang) SPOF gemitigeerd 2026-05-11. Migratie naar eigen hardware = nice-to-have, geen urgentie meer
Supabase self-hostplex (Coolify)blijven of CF D1 Alleen verhuizen als klantcode hier op gaat draaien
Immich · JellyfinplexblijvenNiet bedrijfskritiek, perfect daar
Coolify · PortainerplexblijvenEigen experimenteer-omgeving
Uptime Kuma · GlancesplexblijvenMonitoring zelf is niet kritiek
CamViewer · cams-lxcNUC LXC 102blijvenLokaal = laag latency, klant Lurvink-pad ook hier
TopView zinkerNUC LXC 103blijvenLokaal = onafhankelijk van werk-VPS
Home AssistantNUC VM 100blijvenSmart home, niet zakelijk
Surveillance StationSynologyblijvenNAS native
ComfyUIDikke3090blijvenGPU-bound
claude-mem.dbMacBook lokaal+ Mac mini sync + R2 nightly Werkgeheugen — onvervangbaar
~/.claude configMacBook lokaal+ private GitHub dotfiles repo Bootstrap nieuwe machine in 30 min
Time Machineexterne SSD+ Synology AFP/SMB SSD = lokaal verlies bij brand. NAS = thuis off-laptop
Klant-portalen (Pages)CF PagesblijvenLocatie-onafhankelijk, edge, gratis
PadelClippy webdjeffrey (Plesk)CF Pages + Workers Op termijn migreren weg van Plesk
🆘 Recovery zonder AI

Als ik geen Claude heb om mij te helpen — alle backup-info, restore-commando's en escape-procedures op één plek. Live sinds 2026-05-10.

flowchart LR
  subgraph SRC["📂 Bron · MacBook Pro"]
    HOME["~/.claude · 7.4 GB
~/.claude-mem · 5.3 GB
~/.ssh · keys
~/.config · settings
hele ~/Documents (61 GB raw)"] end subgraph PRIM["🏠 Primary backup · Mac mini"] SFTP["SFTP repo
~/restic-backups/main
10 snapshots
~21 GB op disk"] end subgraph SEC["☁️ Secondary backup · Cloudflare R2"] R2["S3 bucket
noaber-restic-mbp · EU
hele ~/Documents
~15 GB stored
~$0.17/mnd"] end HOME ==>|"NIGHTLY 03:30
LaunchAgent
com.michelmedia.restic-backup"| SFTP HOME ==>|"WEEKLY zo 04:00
LaunchAgent
com.michelmedia.restic-backup-r2"| R2 SFTP -.->|"report → backup.noaber.ai"| BN[("🛡️ backup.noaber.ai")] R2 -.->|"report → backup.noaber.ai"| BN BN -.->|"06:00 · 1 geconsolideerd bericht"| TG[("📱")] classDef bron fill:#1d1d28,stroke:#a78bfa,color:#f5f5f7 classDef prim fill:#0d2818,stroke:#10b981,color:#f5f5f7 classDef sec fill:#0d1f28,stroke:#06b6d4,color:#f5f5f7 class HOME bron class SFTP prim class R2 sec

🔑 Waar staat alles

Encryption passphraseVaultwarden item restic backup passphrase (folder Noaber.ai)
Lokaal: ~/.cache/restic-passphrase.txt (chmod 600)
R2 S3 keysVaultwarden item R2 restic-mbp-noaber S3 keys (folder Noaber.ai)
Lokaal: ~/.config/restic/r2-env (chmod 600)
SSH naar Mac mini~/.ssh/config alias macmini (192.168.2.154)
SSH-key in ~/.ssh/id_rsa
Backup scripts~/.local/bin/restic-backup.sh (Mini SFTP)
~/.local/bin/restic-backup-r2.sh (R2 offsite)
LaunchAgents~/Library/LaunchAgents/com.michelmedia.restic-backup.plist (nightly 03:30)
~/Library/LaunchAgents/com.michelmedia.restic-backup-r2.plist (zondag 04:00)
Logs~/.local/share/restic-backup.log · ~/.local/share/restic-r2-backup.log
Vaultwarden mastermacOS Keychain account bw-vault
Unlock: eval $(~/.local/bin/bw-unlock)

🚨 MBP is stuk — wat nu

  1. Open Mac mini (192.168.2.154) — heeft de meest recente snapshot
  2. Open Terminal en haal credentials uit Vaultwarden:
    bw login michel@helsdingen.com
    bw unlock --raw   # geeft session
    export BW_SESSION="..."
    bw get item "restic backup passphrase"
  3. Schrijf passphrase naar ~/.cache/restic-passphrase.txt (chmod 600)
  4. Restore alleen wat je nu nodig hebt:
    export RESTIC_REPOSITORY=/Users/michelhelsdingen/restic-backups/main
    export RESTIC_PASSWORD_FILE=~/.cache/restic-passphrase.txt
    restic snapshots --compact
    restic restore latest --target ~ --include /Users/michelhelsdingen/.claude
    restic restore latest --target ~ --include /Users/michelhelsdingen/.claude-mem
  5. Werk door op Mac mini. Tijd: ~10 minuten.

🌍 MBP + Mac mini stuk (brand/diefstal) — R2 restore

  1. Nieuwe Mac aanschaffen of huidige toestel met andere persoon
  2. Install: macOS, Homebrew, restic (brew install restic)
  3. Login Cloudflare dashboard via 2FA op telefoon → R2 → API tokens
    De bestaande restic-mbp-noaber token is gebonden aan keys die alleen wij hebben (in BW). Als BW-vault offline is: nieuwe token genereren met je Cloudflare-login.
  4. Set env vars uit BW (op telefoon mobiel-Vaultwarden) of via nieuwe token:
    export AWS_ACCESS_KEY_ID="..."
    export AWS_SECRET_ACCESS_KEY="..."
    export RESTIC_REPOSITORY="s3:https://91a07c8e79b284d2ec64e001fa28fdda.r2.cloudflarestorage.com/noaber-restic-mbp"
    export RESTIC_PASSWORD_FILE=~/.cache/restic-passphrase.txt
    restic snapshots
    restic restore latest --target ~/restored
  5. Tijd: ~30-90 min (afhankelijk van internet + omvang). ~15 GB compressed in R2, expandt naar ~31 GB restore-grootte (hele ~/Documents incl.).

🧪 Wave 0.7 — Kwartaal restore-drill

Onbewezen restore = geen backup. Elk kwartaal: pak random snapshot, restore naar /tmp/restore-test/, verify SHA256 match origineel.

# Vanaf Mini SFTP repo
source ~/.zshrc
export RESTIC_REPOSITORY=sftp:macmini:/Users/michelhelsdingen/restic-backups/main
export RESTIC_PASSWORD_FILE=~/.cache/restic-passphrase.txt
restic restore latest --target /tmp/drill --include /Users/michelhelsdingen/.zshrc
shasum ~/.zshrc /tmp/drill/Users/michelhelsdingen/.zshrc

# Vanaf R2 offsite repo
source ~/.config/restic/r2-env
restic restore latest --target /tmp/drill-r2 --include /Users/michelhelsdingen/.zshrc

# Integrity check (5% sample, snel)
restic check --read-data-subset=5%

Drill-log: schrijf datum + resultaat in infra/RESTORE-PLAYBOOK.md.

📅 Schedule + monitoring

Mini SFTP backupElke nacht 03:30 (LaunchAgent) · ~5-70 sec per run · Telegram notify
R2 offsite backupElke zondag 04:00 (LaunchAgent) · ~70 sec voor delta · Telegram notify
Retention Mini7 daily · 4 weekly · 6 monthly (forget --prune automatisch)
Retention R24 weekly · 6 monthly · 2 yearly (lange-termijn focus)
Health checkWekelijks: restic check --read-data-subset=5% beide repos
Manual runMini: bash ~/.local/bin/restic-backup.sh
R2: bash ~/.local/bin/restic-backup-r2.sh

⚠️ Wat NIET in backup zit (en waarom)

  • ~/Documents (behalve michelmedia/) — code zit in GitHub, niet-code is herbouwbaar of niet-essentieel. _archive/ = oude projecten, niet meer relevant.
  • node_modules, .next, build, dist, DerivedData — herbouwbaar uit package.json/Xcode
  • Photos library, iCloud Drive — die hebben hun eigen Apple-backup
  • Brave/Chrome cache, Time Machine zelf — niet zinvol

Filosofie: backup alleen wat onvervangbaar is. Voor de rest: GitHub voor code, package managers voor deps, vendor-cloud voor managed data.

📡 Backup-monitoring · backup.noaber.ai

Centrale collector — alle backup-jobs rapporteren status naar één Worker. 's Ochtends 06:00 één Telegram-samenvatting i.p.v. 10+ losse nightly meldingen. Multi-tenant via scope-veld. Live sinds 2026-05-13.

flowchart LR
  subgraph JOBS["📦 Backup-jobs · data-laag (ongewijzigd)"]
    direction TB
    BBC["bubbelbal-backup-cron
CF Worker · 02:00 UTC · D1→R2 age"] TOPV["topview-backup-cron
CF Worker · 02:00 UTC · D1→R2 age"] LURV["lurvink-backup-cron
CF Worker · 02:00 UTC · D1→R2 age"] TEKL["tekloeze-rapportage-backup-cron
CF Worker · 02:00 UTC · D1→R2 age"] NUC["LXC 104 NUC-puller
04:00 · pull + decrypt-test → /var/lib"] DRILL["restore-drill.sh
zo 05:30 · terugzet-test per klant"] VAULT["vaultwarden-backup
launchd MBP · 02:30 · encrypted_json → R2"] REST1["restic-backup
launchd MBP · 03:30 · → Mac mini SFTP"] REST2["restic-backup-r2
launchd MBP · zo 04:00 · → R2 offsite"] PAP["backup-paperless-r2
plex VPS bash · 04:15 · tar → GPG → R2"] end subgraph COL["📡 backup.noaber.ai · status-laag"] API["POST /api/report
X-Backup-Token auth"] DB[("D1 backup_event
scope + system_key")] UI["Dashboard · passkey-login
auto-refresh 30s"] CRON["Cron 04:00 UTC
Telegram samenvatting"] end BBC -.->|status| API TOPV -.->|status| API LURV -.->|status| API TEKL -.->|status| API NUC -.->|"offsite heartbeat
via klant-worker"| API DRILL -.->|"restoredrill status"| API VAULT -.->|status| API REST1 -.->|status| API REST2 -.->|status| API PAP -.->|status| API API --> DB DB --> UI DB --> CRON CRON -.->|06:00 CEST| TG[("📱 SpotBot")] classDef job fill:#1d1f28,stroke:#a78bfa,color:#f5f5f7 classDef col fill:#0d2828,stroke:#4FB8B0,color:#f5f5f7 class BBC,TOPV,LURV,TEKL,NUC,DRILL,VAULT,REST1,REST2,PAP job class API,DB,UI,CRON col

🎯 Wat het is

Een dunne monitoring-laag bovenop alle bestaande backup-jobs. De jobs doen hun eigen werk (encryptie, upload naar R2/SFTP) en sturen parallel een 1-regelig status-rapport naar de collector met alleen metadata (status, rows, size, duration). De collector heeft geen backup-data, geen keys, geen control over de jobs — puur observability.

URLbackup.noaber.ai · Worker + D1 + KV + Workers Assets
Auth (UI)WebAuthn passkey · sessie 30d via KV
Auth (API)X-Backup-Token header · SHA-256+pepper hashed in D1
Bron~/Documents/backup-helsdingen/
Cron summary04:00 UTC = 06:00 CEST daily → Telegram (failures bovenaan + OK-overzicht)

🔑 Per-script tokens (least-privilege)

system_keyScopeToken-locatie
bubbelbreinbubbelbalCF wrangler secret BACKUP_COLLECTOR_TOKEN in worker bubbelbal-backup-cron
topview-backuptopviewCF wrangler secret BACKUP_COLLECTOR_TOKEN in worker topview-backup-cron
lurvink-kms-backuplurvinkCF wrangler secret BACKUP_COLLECTOR_TOKEN in worker lurvink-backup-cron
tekloeze-rapportage-backuptekloezeCF wrangler secret BACKUP_COLLECTOR_TOKEN in worker tekloeze-rapportage-backup-cron (2026-05-30)
<klant>-offsiteper klantNUC-puller heartbeat → klant-worker forwardt met dezelfde BACKUP_COLLECTOR_TOKEN
<klant>-restoredrillper klantLXC 104 /etc/restore-drill/<klant>.env · COLLECTOR_TOKEN (klant-scope, chmod 600)
paperless-r2noaberplex VPS /root/.config/backup-collector-token (chmod 600)
restic-mbp-mini + restic-mbp-r2noaberMBP Keychain service backup-collector-token-restic (gedeeld door beide restic-scripts)
vaultwarden-r2noaberMBP Keychain service backup-collector-token-vault

Canonical bron: Vaultwarden item "Backup Noaber.ai — API tokens (collector)" (folder Noaber.ai). Notes bevatten system_keys + host-locaties.

🚀 Nieuwe klant aansluiten

  1. Login op dashboard → /admin/tokens → maak token aan met scope = klantnaam (bv. topview, lurvink)
  2. Plak token in klant-script volgens patroon in backup-helsdingen/scripts/migrate-snippets.md (3 patronen: CF-cron, plex-bash, launchd)
  3. Optioneel: registreer system_keys + expected_frequency_hours via POST /admin/systems voor "missing event" detectie
  4. Later: subdomein status.<klant>.nl via Custom Hostnames met scope-filter — schema ondersteunt multi-tenant zonder schema-wijziging

🛡 Ontwerpprincipes

  • Dunne laag: collector down = backups draaien gewoon door. SPOF-risk minimaal — het ochtend-rapport wordt gemist, niets meer.
  • Failures direct: scripts behouden eigen Telegram voor urgentie. Ochtend-samenvatting is voor totaal-overzicht, niet voor het alert-pad.
  • Per-script tokens: fine-grained revoke, audit per script via last_used_at, beperkte blast-radius bij lek.
  • Multi-tenant via scope: één Worker bedient meerdere klanten. Later per-klant subdomein zonder fork.
  • Geen backup-data in collector: alleen metadata (size, rows, duration, status). Decryptie-keys blijven bij de jobs.

📅 Gemigreerde scripts + schedule

SystemSchedulePatch-datum
bubbelbrein02:00 UTC daily2026-05-13 · CF Worker patch v c7ce7b65
topview-backup02:00 UTC daily2026-05-13 · CF Worker patch v 2148347f
lurvink-kms-backup02:00 UTC daily2026-05-13 · CF Worker patch v a898b784
tekloeze-rapportage-backup02:00 UTC daily2026-05-30 · collector-token aangesloten (worker bestond, rapporteerde nog niet)
<klant>-offsite ×404:00 daily (NUC)2026-05-30 · LXC 104 heartbeat-forward voor alle 4 klanten zichtbaar
<klant>-restoredrill ×4zondag 05:302026-05-30 · tekloeze-restore-drill toegevoegd → 4/4 klanten
vaultwarden-r202:30 daily2026-05-13 · launchd script
restic-mbp-mini03:30 daily2026-05-15 · launchd · central reporting toegevoegd
paperless-r204:15 daily2026-05-13 · plex VPS bash
restic-mbp-r2zondag 04:002026-05-15 · launchd · targets gelijkgetrokken + 1e echte run

Bestaande Telegram-meldingen blijven parallel actief. Pas na 1-2 weken vertrouwen in de ochtend-summary worden success-Telegrams uit de scripts gehaald (failures behouden).

🔮 Toekomstige uitbreidingen

  • Klant-views: status.<klant>.nl per scope-filter
  • Event-detail-pagina: history grafiek per system_key (duration, size trend)
  • Missing-event escalatie: na 48u zonder data → losse Telegram-alert
  • Retention: events >90d archiveren naar R2
  • Noaber Care framework: uitbreiden met DNS-checker + uptime-checker + perf-snapshot pijlers (zelfde D1, event_type veld) — zie TODO-backlog
Actie-prioriteiten

Volgorde van impact-per-uur. Niet alles tegelijk — eerst de SPOFs dichten, dan de hot standby, dan migraties.

✅ DONE · WAVE 0.6
Vaultwarden encrypted export → R2 (offsite, daily)
3-laags beveiliging: master pw + export pw (40 char random in Keychain) + R2 keys. Daily 02:30 LaunchAgent. R2 bucket noaber-vault-backups (EU). Format: encrypted_json passwordProtected, PBKDF2 600k iterations. Lokaal: ~/Backups/vaultwarden (laatste 7). Recovery playbook: infra/RESTORE-VAULTWARDEN.md (3 scenarios). Volgende stap: papieren master pw in offline kluis (eigen actie) + USB-snapshot kwartaal.
Live sinds 2026-05-10
✅ DONE · WAVE 0
restic dual-repo · hele ~/Documents · centrale monitoring
~/.claude two-way Syncthing (13k files) + restic-encrypted backups naar Mac mini (nightly SFTP 03:30) én Cloudflare R2 (weekly offsite zo 04:00). Sinds 2026-05-15 back-uppen beide jobs de volledige ~/Documents (was alleen ~/Documents/michelmedia) — ~31 GB snapshot → ~15 GB stored, mini-repo ~21 GB op disk. Beide scripts identiek (canonical in infra/scripts/) en rapporteren centraal naar backup.noaber.ai → 1 geconsolideerd Telegram om 06:00. Documents uit Syncthing geschrapt 2026-05-10 (case-conflicts; restic dekt het af).
Live sinds 2026-05-07 · uitgebreid 2026-05-15
✅ DONE · WAVE 0.5
restic weekly snapshot → Cloudflare R2 (offsite)
Tweede repo op R2 EU bucket noaber-restic-mbp. Initial 16.6 GB upload klaar in 70 sec. Weekly schedule (zondag 04:00). S3 keys in Vaultwarden item "R2 restic-mbp-noaber S3 keys" + ~/.config/restic/r2-env. Storage cost: ~$0.08/mnd.
Live sinds 2026-05-10
✅ DONE · WAVE 0.7
Restore-drill van beide repos
Test-restores uit zowel Mini SFTP als R2 — files SHA256-match origineel ✓. Restic check --read-data-subset=5%: no errors op beide repos. Quarterly drill ritueel ingericht.
Live sinds 2026-05-10
✅ DONE · WAVE 0.8
Paperless SPOF gemitigeerd — 3-laags backup live
Laag 1: plex lokaal tar.gz (03:30, 30d). Laag 2: Synology NAS via Tailscale rsync (03:45). Laag 3: GPG-encrypted tar.gz.gpg → R2 noaber-paperless-backups (04:15, 30d daily + 12w weekly). Restore-drill geslaagd: 82M encrypted, 28 docs intact in sqlite. Recovery-doc: RESTORE-PAPERLESS.md.
Live sinds 2026-05-11
✅ DONE · WAVE 0.9
Backup-monitoring collector live — 7 jobs gemigreerd over 4 scopes
backup.noaber.ai met passkey-login + multi-tenant scope-architectuur. Vervangt 10+ losse nightly Telegram-meldingen door 1 ochtend-samenvatting 06:00 CEST. Gemigreerd:
  • scope bubbelbal: bubbelbal-backup-cron (BubbelBrein klant-data)
  • scope topview: topview-backup-cron (manual trigger geverifieerd)
  • scope lurvink: lurvink-backup-cron (manual trigger geverifieerd)
  • scope noaber: vaultwarden-r2 + restic-mbp-mini + restic-mbp-r2 + paperless-r2
Per-script tokens in Vaultwarden + Keychain + plex config. Sinds 2026-05-14: per-job success-Telegrams verwijderd (zie Wave 0.11) — alleen 06:00 rapport + directe failures. Next: BubbelBrein versionering + DNS/uptime/perf-pijlers als Noaber Care framework. Bron: ~/Documents/backup-helsdingen/.
Live sinds 2026-05-13
✅ DONE · WAVE 0.10
dekei1.ltcdekei.nl gemigreerd naar Cloudflare Workers + D1 — plex-onafhankelijk
Eerste klant-app volledig weg van self-hosted Supabase op plex. Frontend van Coolify (plex tunnel dekei1-app:3000) naar Cloudflare Worker via @opennextjs/cloudflare (Next.js 16.2). Backend van Postgres (Supabase op plex) naar D1 SQLite dekei1 (id 6d7d56e8…). 6 wedstrijden + 36 beschikbaarheidsrijen gemigreerd zonder data-verlies. Workers Custom Domain met auto-SSL. Code-rewrite van supabase.from()getCloudflareContext().env.DB.prepare() met SQLite UPSERT. Plex-uitval = site blijft staan. Tabellen dekei1_* in plex Supabase blijven voor soak-test tot na 23 mei. Bron: ~/Documents/dekei1/dekei1/.
Live sinds 2026-05-14 · cutover 14:27 CEST
✅ DONE · WAVE 0.11
Telegram-consolidation — per-job successes uitgeschakeld, 06:00 rapport enige routine
Operationeel model uit Wave 0.9 doorgetrokken: alle 8 backup-bronnen stoppen met success-Telegrams (3 MBP launchd scripts + 3 CF Workers gedeployed + plex paperless-r2 + NUC topview-backup-pull + padelclippy-cron). Failures houden hun directe Telegram (urgentie-pad ongewijzigd). D1 catalog opgeschoond: 19 → 7 systeem-registraties (dubbele noaber/* + 6 test/smoketest entries verwijderd, ook noaber/cashspot die nooit rapporteerde). PadelClippy outreach cron uit (3 schedules: daily digest, sweep, weekly report — endpoint blijft voor handmatige run). CashSpot health-check cron op plex uitgeschakeld (/opt/cashspot-health/nightly-check.sh — script behouden voor revival). Tradingbot daily 09:00 portfolio-summary uit (evening snapshot 23:00 blijft voor data-historie). Verwacht resultaat: 1 nacht-Telegram (06:00 backup-rapport) i.p.v. ~10.
Live sinds 2026-05-14
P3 · DOTFILES
Private GitHub dotfiles repo + bootstrap-script
~/.claude, ~/.zshrc, install-script die op nieuwe Mac alles inricht behalve secrets (die komen via Vaultwarden CLI). Recovery-tijd nieuwe Mac: 30 min.
~2 uur
P3 · DOC
Recovery doc in Vaultwarden + papier in kluis
"Mac is weg, wat nu?" met stap-voor-stap commando's. Master password + bootstrap-credentials in offline kluis.
~30 min
P4 · LANGE TERMIJN
Vaultwarden migratie naar NUC LXC
Nieuwe LXC op Proxmox, Vaultwarden Docker, restore vanuit plex backup, DNS swap (vault.helsdingen.com → nieuwe tunnel). Eindresultaat: credential-bron op eigen hardware, plex VPS los te koppelen zonder paniek.
~3 uur
P4 · ROL
Oude MBP als clean reference machine inrichten
Vers macOS install + bootstrap-script + Vaultwarden CLI. Maandelijks image-refresh ritueel. Cold standby als brand/diefstal/serieuze pech.
~2-3 uur