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

+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# Sicherung einer selbst gehosteten TeamVis-Instanz mit eigener Datenbank
# (install.sh, Variante „eigene DB“): die Schemas public + storage als
# pg_dump im Custom-Format und die Storage-Dateien (volumes/storage).
#
# Liegt im Instanz-Verzeichnis (neben docker-compose.yml) und läuft per Cron:
# 15 3 * * * /bin/bash /pfad/instanz/backup.sh >> $HOME/backups/<instanz>/backup.log 2>&1
#
# Nicht gesichert wird die .env: Sie enthält alle Secrets und gehört in einen
# Passwort-Safe. Ohne sie (JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY,
# POSTGRES_PASSWORD) lässt sich die Instanz aus den Dumps aber nicht
# wiederherstellen. Wiederherstellung: README.md → „Sicherung und
# Wiederherstellung“.
#
# PUSH_URL (optional, Zeile in $BACKUP_DIR/push.env): Push-Monitor in Uptime
# Kuma. Wird nur nach einem vollständigen Lauf aufgerufen — bleibt er aus,
# alarmiert Kuma. So fällt auch ein Cron auf, der gar nicht läuft.
set -euo pipefail
INSTANCE_DIR="${INSTANCE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
NAME="$(basename "$INSTANCE_DIR")"
BACKUP_DIR="${BACKUP_DIR:-$HOME/backups/$NAME}"
KEEP_DAYS="${KEEP_DAYS:-30}"
[ -f "$BACKUP_DIR/push.env" ] && . "$BACKUP_DIR/push.env"
cd "$INSTANCE_DIR"
umask 077
mkdir -p "$BACKUP_DIR"
STAMP="$(date +%F-%H%M)"
DB="$BACKUP_DIR/db-$STAMP.dump"
FILES="$BACKUP_DIR/storage-$STAMP.tar.gz"
trap 'rm -f "$DB.part" "$FILES.part"' EXIT
# public = TeamVis-Daten. storage = Buckets und Objekt-Metadaten, samt der
# Migrationstabelle der Storage-API — so legt die API beim Wiederherstellen
# nichts neu an. auth und vault legt das Postgres-Image selbst an, TeamVis
# nutzt sie nicht.
docker compose exec -T db sh -c \
'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -h localhost -U supabase_admin -d "$POSTGRES_DB" -Fc -n public -n storage' \
> "$DB.part"
# Ein abgeschnittener Dump fällt beim Lesen des Inhaltsverzeichnisses auf.
TOC="$(docker compose exec -T db pg_restore -l < "$DB.part")"
if ! grep -q "TABLE DATA public employees" <<< "$TOC"; then
echo "$(date -Is) FEHLER: Dump unvollständig" >&2
exit 1
fi
# --xattrs ist Pflicht: Die Storage-API (Datei-Backend) legt Content-Type und
# Cache-Control jeder Datei als erweiterte Attribute (user.supabase.*) ab.
# Ohne sie liefert eine wiederhergestellte Instanz die Dateien mit 500 aus
# (am 09.10.2026 im Wiederherstellungstest gefunden).
tar --xattrs --xattrs-include='user.*' -czf "$FILES.part" -C volumes storage
gzip -t "$FILES.part"
mv "$DB.part" "$DB"
mv "$FILES.part" "$FILES"
find "$BACKUP_DIR" \( -name 'db-*.dump' -o -name 'storage-*.tar.gz' \) -mtime +"$KEEP_DAYS" -delete
echo "$(date -Is) ok $(basename "$DB") $(stat -c %s "$DB") Bytes, $(basename "$FILES") $(stat -c %s "$FILES") Bytes"
if [ -n "${PUSH_URL:-}" ]; then
curl -fsS -m 10 "$PUSH_URL?status=up&msg=OK" >/dev/null || echo "$(date -Is) Push an Uptime Kuma fehlgeschlagen" >&2
fi