TeamVis Self-Host-Bundle v0.56.2

This commit is contained in:
TeamVis Release committed 2026-10-10 23:39:23 +02:00
1 parent f53579d3a4
commit 6da3cc2283
11 files changed
+432 -30

No files matched your search

+53 -3
View File
@@ -195,15 +195,63 @@ ganze Block).
4. **Keys sind JWTs:** `ANON_KEY`/`SERVICE_ROLE_KEY` sind mit `JWT_SECRET`
signierte Tokens (`gen-keys.mjs`). Wird `JWT_SECRET` geändert, müssen beide
Keys neu erzeugt werden.
5. **Backups:** jetzt liegt die DB beim Kunden. Postgres-Volume + Storage-
Volume sichern (`pg_dump` + `volumes/storage`). Beim externen Supabase war
das deren Sache.
5. **Backups:** jetzt liegt die DB beim Kunden — siehe „Sicherung und
Wiederherstellung“ unten. Beim externen Supabase war das deren Sache.
6. **Modul-Rollout:** frische Instanz startet minimal (nur Visitenkarten).
Danach unter **Admin → Funktionen** gestaffelt freischalten
(siehe `docs/NEUKUNDE.md` §5a).
---
## Sicherung und Wiederherstellung
Gilt für die Variante mit eigener Datenbank (Variante B, `install.sh`).
Beide Skripte liegen im Instanz-Verzeichnis neben `docker-compose.yml`.
**Sichern — `backup.sh`**, täglich per Cron des Betriebsnutzers:
```bash
15 3 * * * /bin/bash /pfad/instanz/backup.sh >> $HOME/backups/<instanz>/backup.log 2>&1
```
- Datenbank: Schemas `public` (TeamVis) und `storage` (Buckets, Objekt-
Metadaten, Migrationsstand der Storage-API) als `db-JJJJ-MM-TT-HHMM.dump`
(Custom-Format). Das Skript prüft das Inhaltsverzeichnis — ein
abgeschnittener Dump bricht mit Fehler ab.
- Dateien: `volumes/storage` als `storage-….tar.gz` **mit erweiterten
Attributen** (`tar --xattrs`). Die Storage-API speichert Content-Type und
Cache-Control jeder Datei als `user.supabase.*`-Attribut; ohne sie liefert
eine wiederhergestellte Instanz jede Datei mit HTTP 500 aus.
- Ablage `$HOME/backups/<instanz>` (Verzeichnis `700`, Dateien `600`),
30 Tage Aufbewahrung (`KEEP_DAYS`). Optional meldet jede erfolgreiche
Sicherung an einen Push-Monitor (Uptime Kuma): Zeile `PUSH_URL=…` in
`$HOME/backups/<instanz>/push.env`.
- **Nicht** gesichert: die `.env`. Sie gehört in einen Passwort-Safe — ohne
die originalen Secrets (`JWT_SECRET`, Keys, `POSTGRES_PASSWORD`) passen
Dumps und Instanz nicht mehr zusammen.
- Die Sicherungen liegen auf demselben Host. Gegen Hostverlust zusätzlich
an einen zweiten Ort kopieren (VM-Snapshot allein ersetzt das nicht: Er
sichert die laufende Datenbank nur absturzkonsistent).
**Wiederherstellen — `restore.sh`**, nur in eine **leere** Datenbank (neuer
Host, neues Volume, Totalverlust):
```bash
cd /pfad/instanz # docker-compose.yml + .env aus dem Passwort-Safe
bash restore.sh ~/backups/<instanz>/db-….dump ~/backups/<instanz>/storage-….tar.gz
```
Das Skript startet die Datenbank, setzt die Rollen-Passwörter und
`service_role bypassrls` (Cluster-Eigenschaften, nicht im Dump), spielt den
Dump ein (ohne das vom Image angelegte Schema `storage` selbst), entpackt die
Dateien mit Attributen und startet alle Dienste. Es bricht ab, wenn schon
TeamVis-Daten in der Datenbank oder Dateien in `volumes/storage` liegen.
Am 09.10.2026 mit einer echten Instanz (50 Karten, 5 Dateien) in einem
isolierten Wegwerf-Projekt getestet: Zeilenzahlen gleich, PostgREST liest mit
Service- und Anon-Key, alle Dateien über die Storage-API abrufbar und
byte-gleich.
## Footprint (grob)
| | Container | RAM (Daumenregel) |
@@ -258,3 +306,5 @@ war im localhost-Test nicht aktiv).
| `Caddyfile.example` | TLS-Ingress (App- + Supabase-Domain) |
| `gen-keys.mjs` | erzeugt JWT_SECRET + ANON_KEY + SERVICE_ROLE_KEY |
| `bootstrap.sh` | Keys + Stack + Schema + Admin in einem Rutsch |
| `backup.sh` | tägliche Sicherung (Datenbank + Storage mit Attributen) |
| `restore.sh` | Wiederherstellung in eine leere Instanz |