# Server-Umzug: netralax.cloud -> netralax.de Einmalige Migration des selbst gehosteten Chat-Backends vom **alten VPS** (`46.225.156.249`, `*.netralax.cloud`) auf einen **neuen, leeren VPS** (`*.netralax.de`). Der neue Server bedient anschliessend **beide** Domains, damit bereits installierte Desktop-/Mobile-Clients (die alte Hostnamen und den alten anon-JWT fest eingebaut haben) weiterlaufen, bis sie sich selbst aktualisieren. > Diese Skripte sind bewusst getrennt von `scripts/prod/`. `scripts/prod/config.sh` > kennt nur den jeweils **aktiven** Server; der Umzug braucht **beide** Hosts und > hat deshalb seine eigene `scripts/migrate/config.sh`. ## Dateien | Datei | Wo ausführen | Zweck | |-------|--------------|-------| | `config.sh` | – | Gemeinsame Konfiguration (alter + neuer Host, SSH-Helfer). Wird von den anderen Skripten eingebunden. | | `01-bootstrap-new-server.sh` | **auf dem neuen VPS** (als root / sudo) | Richtet den leeren Server ein: Docker, ufw, Supabase-Clone, LiveKit-Verzeichnis, Caddy, Update-Host, Deploy-User. | | `02-migrate-data.sh` | **auf dem Entwickler-Laptop** | Überträgt Postgres-Daten (pg_dumpall) und die Storage-Objekte (rsync) von alt nach neu. | ## Voraussetzungen / Einrichtung (einmalig) 1. **Neue Server-IP — bereits eingetragen.** `scripts/migrate/config.sh` hat `NEW_HOST="141.95.34.204"` und `NEW_USER="debian"`. (Der `require_new_host`- Guard greift nur, falls der Platzhalter wieder drinsteht.) 2. **SSH-Zugriff.** Vom Laptop muss `ssh prox@46.225.156.249` (alt) **und** `ssh debian@141.95.34.204` (neu) ohne Passwort funktionieren: ``` ssh-copy-id prox@46.225.156.249 ssh-copy-id debian@141.95.34.204 ``` Für den direkten Storage-Transfer (Server-zu-Server) muss zusätzlich der **alte** Server per SSH auf den **neuen** zugreifen können. Klappt das nicht, fällt `02-migrate-data.sh` automatisch auf den Umweg über den Laptop zurück. 3. **Skripte ausführbar machen:** ``` chmod +x scripts/migrate/*.sh ``` ## Ablauf (Reihenfolge unbedingt einhalten) 1. **Bootstrap auf dem neuen Server.** Skript hochladen und als root ausführen: ``` scp scripts/migrate/01-bootstrap-new-server.sh debian@141.95.34.204:/tmp/ ssh debian@141.95.34.204 'sudo bash /tmp/01-bootstrap-new-server.sh' ``` Das Skript ist idempotent (mehrfaches Ausführen schadet nicht) und gibt am Ende einen **NEXT STEPS**-Block aus. 2. **Secrets eintragen.** `/opt/supabase/.env` auf dem neuen Server befüllen. Diese Werte **1:1 vom alten Server kopieren** (sonst brechen eingebaute Tokens, Sessions und Web-Push): `POSTGRES_PASSWORD`, `JWT_SECRET`, `ANON_KEY`, `SERVICE_ROLE_KEY`, `SECRET_KEY_BASE`, `VAULT_ENC_KEY`, `PG_META_CRYPTO_KEY`, alle `SMTP_*`, `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `VAPID_SUBJECT`, `PUSH_FANOUT_SHARED_SECRET`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`. Auf die **neue** Domain zeigen: `SITE_URL`, `API_EXTERNAL_URL`, `SUPABASE_PUBLIC_URL`, `SUPABASE_URL` = `https://supabase.netralax.de`, `LIVEKIT_URL` = `wss://livekit.netralax.de`. `ADDITIONAL_REDIRECT_URLS` (komma-getrennt, **ohne Leerzeichen**) muss enthalten: `chatapp://auth/callback`, `netralax://auth/callback` sowie `https://supabase.netralax.de` und `https://supabase.netralax.cloud`. 3. **Server-Konfig platzieren.** - `infra/livekit/docker-compose.prod.yml.example` -> `/opt/livekit/docker-compose.yml` (Prod-Compose: host-networking, mountet `livekit.yaml` + `coturn.conf` + `/etc/letsencrypt`; das Dev-Compose taugt **nicht** für Prod). - `infra/livekit/livekit.prod.yaml.example` -> `/opt/livekit/livekit.yaml` (`rtc.use_external_ip: true`, **kein** `node_ip: 127.0.0.1`, `keys:`-Block identisch zu `LIVEKIT_API_KEY/SECRET` aus der `.env`). - `infra/livekit/coturn.prod.conf.example` -> `/opt/livekit/coturn.conf` (`external-ip` = öffentliche IP des neuen VPS, TLS-Cert für `turn.netralax.de`). - `infra/caddy/Caddyfile` -> `/etc/caddy/Caddyfile`, danach `systemctl reload caddy`. Caddy bedient **beide** Domains (.de und .cloud). 4. **Stacks starten – DB zuerst einmal hochfahren**, damit die Supabase-Init- Skripte die Rollen anlegen (vor dem Restore): ``` ssh debian@141.95.34.204 'cd /opt/supabase && docker compose up -d db && sleep 20' ``` 5. **Schreibzugriffe auf dem ALTEN System einfrieren** (Wartungsmodus). Sonst landen während des Umzugs neue Uploads/Zeilen nur auf einer Seite und DB + Storage werden inkonsistent. 6. **Daten migrieren** (vom Laptop). Erst der Trockenlauf, dann die Migration: ``` ./scripts/migrate/02-migrate-data.sh --check # nur Pre-Flight, keine Änderung ./scripts/migrate/02-migrate-data.sh # fragt nach Bestätigung ``` Das Skript dumpt den **gesamten** Cluster per `pg_dumpall` und spielt ihn auf dem neuen Server ein, danach rsync der Storage-Objekte. `push-migrations.sh` **nicht** erneut ausführen – die Migrationen sind bereits im Dump enthalten. 7. **DNS umstellen.** A-Records für **beide** Domains auf die neue IP zeigen lassen: `supabase.netralax.de` / `.cloud`, `livekit.netralax.de` / `.cloud`, `turn.netralax.de`, `update.netralax.de` / `.cloud`. 8. **Update-Artefakte spiegeln.** electron-updater-Dateien (`latest.yml`, `*.exe`, `changelog.json`) unter `/var/www/updates/windows` ablegen, sodass **sowohl** `update.netralax.de` **als auch** `update.netralax.cloud` sie ausliefern. Nur so können alte (.cloud-)Clients die Umstiegs-Version ziehen. ## Sicherheitshinweise - **`JWT_SECRET`, `ANON_KEY`, `SERVICE_ROLE_KEY`** müssen byteweise identisch vom alten Server stammen, **bevor** der erste Client den neuen Server trifft – sonst werden alle eingebauten Tokens abgelehnt und alle Sessions fliegen raus. - **`POSTGRES_PASSWORD`** muss vor dem Restore identisch gesetzt sein, weil der Dump die Rollen-Passwort-Hashes mitbringt. Sonst können sich die internen Dienste (auth/rest/storage) nach dem Restore nicht mehr an Postgres anmelden. - **VAPID-Schlüsselpaar** identisch übernehmen, sonst sind alle bestehenden Web-Push-Abos ungültig. - **Medien-/TURN-Ports** müssen in ufw offen sein (7880/7881 tcp, 50000-50100 udp, coturn 3478 tcp+udp, 5349 tcp, 50200-50300 udp) – sonst haben Anrufe kein Audio/Video. Diese Ports laufen **nicht** über Caddy. - **TURNS auf 5349** braucht ein eigenes TLS-Zertifikat für `turn.netralax.de` auf der Platte (Pfade in `coturn.conf`) – ein reines Caddy-Zertifikat reicht nicht. - **Alten VPS nicht abschalten**, bevor die `.cloud`-DNS-Einträge auf den neuen Server zeigen und alte Clients Zeit zum Auto-Update hatten. - Beim Restore werden harmlose `already exists`-Fehler für vorhandene Rollen (`supabase_admin`, `postgres` …) ausgegeben – das ist gewollt (`ON_ERROR_STOP=0`). `02-migrate-data.sh` scannt die Restore-Ausgabe **automatisch** auf echte `ERROR/FATAL/PANIC` und **bricht vor dem Storage- rsync ab**, wenn welche übrig bleiben (Override: `FORCE_RESTORE_OK=1`). Danach macht es eine Zeilen-Paritätsprüfung (alt vs. neu) über die tragenden Tabellen.