From c14aef9f85cf48ef9a551a320d34b0cfebe8b284 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 6 May 2026 20:39:01 +0200 Subject: [PATCH] =?UTF-8?q?docs(infra):=20Mac-Mini=20=E2=86=94=20Windows-G?= =?UTF-8?q?PU-Box=20workload-split=20=E2=80=94=20Plan=20Option=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hilfsdienste (Monitoring, Forgejo, Glitchtip, Umami) wandern von der auslast­ungs-kritischen Mac-Mini-Box auf die Windows-GPU-Box, die ohnehin 95 % System-RAM idle hat. Production-Hot-Path bleibt auf dem Mini, kein Geld ausgegeben, Single-Point-of-Failure am Standort reduziert. Stand 2026-05-06: Phase 0–2b shipped (WSL2-Docker, Grafana cross-box, Forgejo, Umami healthy). Phase 2c (Loki+VM+Alerts) und Phase 4 (Cloudflare-Cutover für grafana.mana.how) brauchen eigene Sessions — beides Pre-existing-Mis-config-Aufräumen, kein Architektur-Risiko. Hardware-Inventar in WINDOWS_GPU_SERVER_SETUP.md ergänzt: Ryzen 9 5950X, 64 GB DDR4, RTX 3090, 660 GB frei C:. WSL2 auf 24 GB / 12 vCPU gedeckelt damit AI-Scheduled-Tasks > 30 GB Reserve haben. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/PLAN_OPTION_C.md | 357 +++++++++++++++++++++++++++++++ docs/WINDOWS_GPU_SERVER_SETUP.md | 24 +++ 2 files changed, 381 insertions(+) create mode 100644 docs/PLAN_OPTION_C.md diff --git a/docs/PLAN_OPTION_C.md b/docs/PLAN_OPTION_C.md new file mode 100644 index 000000000..a9f1790ea --- /dev/null +++ b/docs/PLAN_OPTION_C.md @@ -0,0 +1,357 @@ +# Plan — Option C: Workload-Split Mac Mini ↔ Windows-GPU-Box + +**Stand:** 2026-05-06 +**Ziel:** Nicht-zeitkritische Hilfsdienste (Monitoring, Forgejo, Glitchtip, Umami) +auf die Windows-GPU-Box (64 GB RAM, derzeit 95 % idle System-RAM) verlagern. +Single-Point-of-Failure innerhalb des Standorts entfernen, ohne Geld auszugeben. +Production-Hot-Path bleibt unverändert auf dem Mini. + +## Status + +| Phase | Stand | Anmerkung | +|---|---|---| +| Phase 0 — Vor-Setup | ✅ | Hardware bestätigt (Ryzen 9 5950X / 64 GB / RTX 3090 / 660 GB frei C:), in `WINDOWS_GPU_SERVER_SETUP.md` dokumentiert | +| Phase 1 — WSL2 + Docker | ✅ | War schon eingerichtet (Ubuntu 24.04, Docker 29.4.1, systemd). `.wslconfig` erweitert um `memory=24GB`, `processors=12`, `swap=8GB`, `vmIdleTimeout=-1` | +| Phase 2a — Grafana auf GPU-Box | ✅ | Container `mana-mon-grafana` läuft auf `:8000`, Cross-Box-Datasources testen erfolgreich (Prometheus/VM, Loki, Business Metrics). DB-Datasources schlagen fehl wegen Pre-existing-Mis-config (DBs heißen `mana_admin`, nicht `mana`; keine `glitchtip` DB) | +| Phase 2b — Umami + Forgejo | ✅ | Beide healthy auf GPU-Box. Glitchtip übersprungen — Mini-Glitchtip ist bereits im Broken-State (DB `glitchtip` existiert nicht in Postgres, läuft nur in Degraded-Mode), Migration würde Bug nicht heilen | +| Phase 2c — VM + Loki + Alerts | ⏳ | Erfordert `prometheus.yml`-Rewrite mit ~30 Mini-IP-Targets — eigene Session | +| Phase 3 — Daten-Migration | n/a | Alle migrierten Apps lesen Mini-Postgres direkt — keine separate Datenmigration | +| Phase 4 — Cloudflare-Cutover | ⏳ | User-action: `grafana.mana.how` als Public-Hostname im `mana-gpu-server`-Tunnel via Dashboard, dann DNS umrouten | +| Phase 5 — Mini-Compose aufräumen | ⏳ | Erst nach Cutover | + +### Was läuft heute (2026-05-06) auf der GPU-Box + +``` +WSL2 (Ubuntu 24.04, 24 GB RAM-Limit, 12 vCPU, vmIdleTimeout=-1) +└── Docker (systemd-managed, auto-start) + ├── photon (eclipse-temurin:21-jre, port 2322) — Geocoder-Backend für Mini-mana-geocoding (Pre-existing) + ├── mana-mon-grafana (grafana:10.4.1, port 8000) — Phase 2a + │ ├── volume: mana-grafana-data + │ ├── bind: /srv/mana/monitoring/grafana/{provisioning,dashboards} + │ └── datasources: alle URLs rewritten auf 192.168.178.131 + ├── mana-core-forgejo (forgejo:11, port 3041) — Phase 2b + │ ├── bind: /srv/mana/forgejo-data:/data + │ ├── DB-host: 192.168.178.131:5432 (LAN → Mini-Postgres) + │ └── app.ini frisch generiert mit INSTALL_LOCK + neuen Secret-Keys + └── mana-mon-umami (umami:postgresql-v2.18.0, port 8010) — Phase 2b + ├── DB: 192.168.178.131:5432/umami + └── APP_SECRET: identisch mit Mini-Setup (Sessions kompatibel) +``` + +**WSL-Keepalive:** Scheduled Task `MANA_WSL_Keepalive` (Trigger: AtLogOn + AtStartup, +Restart bei Failure) hält `wsl.exe -d Ubuntu-24.04 --exec /bin/sleep infinity` +als langlebigen Windows-Prozess offen → WSL-VM idled nicht aus, Container +überleben SSH-Session-Pausen. + +--- + +## 0. Voraussetzungen + +| | | +|---|---| +| Mac Mini SSH | `ssh mana-server` (192.168.178.131, User `mana`) — **OK** | +| GPU-Box SSH | `ssh mana-gpu` (192.168.178.11, User `tills`) — **derzeit offline** | +| GPU-Box muss vor Phase 1 erreichbar sein | Box einschalten, Network-Profile auf "Privat" setzen (Doku §1 in `WINDOWS_GPU_SERVER_SETUP.md`) | +| Live-Tunnel-Config Mac Mini | `/Users/mana/projects/mana-monorepo/cloudflared-config.yml` (geladen via LaunchAgent) | +| Mac-Mini-Tunnel-UUID | `1435166a-0e3f-4222-8de6-744f32cea5c9` | +| GPU-Box-Tunnel-UUID | `83454e8e-d7f5-4954-b2cb-0307c2dba7a6` (Token-managed im Cloudflare-Dashboard) | + +## 1. Service-Inventar — was wandert, was bleibt + +### Wandert auf GPU-Box (WSL2/Docker) + +| Container | Host-Port (Mini) | Image | Daten-Volumen | Anmerkung | +|---|---|---|---|---| +| `grafana` | 8000 | `grafana/grafana:10.4.1` | `mana-grafana-data` (46 MB) | Dashboards + Provisioning aus Repo bind-mount | +| `victoriametrics` | 9090 | `victoriametrics:v1.99.0` | `mana-victoria-data` (988 MB) | Scrapes über LAN auf Mini-Exporter umkonfigurieren | +| `loki` | 3100 | `grafana/loki:3.0.0` | `mana-loki-data` (4 MB) | Promtail auf Mini schickt zu `192.168.178.11:3100` | +| `pushgateway` | 9091 | `prom/pushgateway:v1.7.0` | — | | +| `blackbox-exporter` | 9115 | `prom/blackbox:v0.25.0` | — | Probt von außen — sogar besser, wenn nicht auf der Mini-Box | +| `vmalert` | 8880 | `victoriametrics/vmalert:v1.99.0` | — | Alerts-Dir aus Repo bind-mount | +| `alertmanager` | 9093 | `prom/alertmanager:v0.27.0` | `mana-alertmanager-data` (8 KB) | | +| `alert-notifier` | 9095 | `alert-notifier:local` | — | Lokales Image — auf GPU-Box neu bauen | +| `umami` | 8010 | `umami:postgresql-v2.18.0` | (DB only) | DB `umami` bleibt auf Mini-Postgres, App ruft via 192.168.178.131:5432 | +| `glitchtip` + `worker` | 8020 | `glitchtip:latest` | (DB only) | DB-Name TBD beim Migrieren — wahrscheinlich auch in Mini-Postgres | +| `forgejo` (re-aktivieren) | 3041 | `codeberg.org/forgejo/forgejo:11` | (frisch oder Volume-Restore) | Container läuft heute **nicht**; DB-Tabelle vorhanden | + +### Bleibt auf Mac Mini + +**Production Hot-Path:** `postgres`, `postgres-backup`, `redis`, `minio`, +`minio-init`, `mana-auth`, `mana-api`, `mana-app-web`, `mana-sync`, +`mana-credits`, `mana-user`, `mana-subscriptions`, `mana-events`, +`mana-geocoding`, `mana-analytics`, `mana-research`, `mana-ai`, `mana-media`, +`mana-crawler`, `mana-notify`, `mana-search`, `mana-landing-builder`, +`api-gateway`, `mana-llm` (Proxy), `mana-app-manavoxel-web`, +`mana-app-uload-server`, `mana-app-llm-playground`, `mana-admin`, `mana-mail`, +`mana-status-gen`, `mana-infra-landings` (nginx), `memoro-server`, +`memoro-audio-server`, `memoro-landing`, `chorportal-app` + `chorportal-prod-postgres` ++ `chorportal-prod-minio`, `news-ingester`, `mana-verdaccio` (npm-Registry, +Migration auf GPU-Box ist späterer Schritt). + +**Box-lokale Helpers (laufen auf jeder Box separat):** +- `node-exporter` (Host-Metriken) +- `cadvisor` (lokale Docker-Metriken) +- `promtail` (lokaler Log-Shipper) +- `watchtower` (lokaler Docker-Updater) +- `postgres-exporter` (bleibt nur auf Mini, weil Postgres dort) +- `redis-exporter` (bleibt nur auf Mini) + +### Native Prozesse Mini (kein Docker, bleiben unverändert) + +`who-server` (PM2), `who-web` (LaunchAgent), `cloudflared` (Mini-Tunnel), +`colima`, GitHub-Runner, `actions.runner.Memo-2023-mana-monorepo.mac-mini`. + +## 2. Cloudflare-Routing — Vorher / Nachher + +| Hostname | Vorher | Nachher | Tunnel | +|---|---|---|---| +| `grafana.mana.how` | Mini :8000 | GPU-Box :8000 | mana-gpu-server | +| `git.mana.how` | Mini :3041 (heute 502, da Forgejo aus) | GPU-Box :3041 | mana-gpu-server | +| `glitchtip.mana.how` | Mini :8020 | GPU-Box :8020 | mana-gpu-server | +| `stats.mana.how` (Umami) | Mini :8010 | GPU-Box :8010 | mana-gpu-server | +| `status.mana.how` | Mini :4400 (nginx) | **bleibt Mini** (status-page-gen schreibt in landings dir) | mana-server | +| Alle anderen `*.mana.how` | Mini | **unverändert Mini** | mana-server | + +Hinzufügen im Cloudflare-Dashboard (Zero Trust → Networks → Tunnels → +`mana-gpu-server` → Public Hostnames): + +``` +grafana.mana.how → http://localhost:8000 +git.mana.how → http://localhost:3041 +glitchtip.mana.how → http://localhost:8020 +stats.mana.how → http://localhost:8010 +``` + +DNS-CNAMEs zeigen heute auf den Mini-Tunnel und müssen umgeschwenkt werden: + +```sh +ssh mana-server '/opt/homebrew/bin/cloudflared tunnel route dns \ + --overwrite-dns 83454e8e-d7f5-4954-b2cb-0307c2dba7a6 grafana.mana.how' +# … pro Hostname +``` + +## 3. Phasen + +### Phase 0 — Vor-Setup (10 min, kein Risiko) + +1. GPU-Box einschalten, Network-Profile auf "Privat" setzen, SSH testen. + ```sh + ssh mana-gpu "Get-NetConnectionProfile; Get-Service sshd" + ``` +2. CPU/RAM/Disk dokumentieren in `docs/WINDOWS_GPU_SERVER_SETUP.md`: + ```sh + ssh mana-gpu "Get-ComputerInfo | Select-Object CsTotalPhysicalMemory,CsNumberOfLogicalProcessors,WindowsVersion; Get-PSDrive C" + ``` +3. Bestätigen, dass die AI-Scheduled-Tasks ungestört laufen: + ```sh + ssh mana-gpu "Get-ScheduledTask -TaskName Mana* | Select-Object TaskName,State" + curl -s https://gpu-llm.mana.how/health + ``` + +### Phase 1 — WSL2 + Docker auf GPU-Box (1 h) + +1. WSL2 + Ubuntu 24.04 installieren (falls nicht vorhanden): + ```powershell + wsl --install -d Ubuntu-24.04 --no-launch + wsl --set-default-version 2 + ``` +2. `.wslconfig` in `C:\Users\tills\.wslconfig` erstellen — **WSL2 auf 16 GB RAM + begrenzen**, damit AI-Tasks ihren System-RAM behalten: + ```ini + [wsl2] + memory=16GB + processors=8 + swap=4GB + localhostForwarding=true + ``` +3. WSL starten, User anlegen, dann: + ```sh + sudo apt update && sudo apt install -y ca-certificates curl + curl -fsSL https://get.docker.com | sudo sh + sudo usermod -aG docker $USER + # systemd in WSL aktivieren: + sudo tee /etc/wsl.conf >/dev/null < 30 GB Reserve behalten. + +Bestand 2026-05-06: ein **Photon-Geocoder** (eclipse-temurin Java, Port 2322) +läuft unter Docker in WSL2 als Backend für `mana-geocoding` auf dem Mac Mini. + --- ## Checkliste: Nach jedem Neustart