Files
byGalax 5bc30c950c feat(infra): migrate self-hosted backend to netralax.de
Move Supabase + LiveKit from the netralax.cloud VPS to a new netralax.de server. Adds the migration runbook (docs/), one-time move scripts (scripts/migrate/), and prod Caddy/LiveKit config templates (infra/). Repoints the desktop publish/changelog URLs and prod ops config to .de. JWT_SECRET + VAPID copied identically so already-installed clients keep working; the new server also serves the legacy .cloud hostnames.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 19:39:04 +02:00

7.0 KiB
Raw Permalink Blame History

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.