TeamVis Self-Host-Bundle v0.56.2
This commit is contained in:
1 parent
f53579d3a4
commit
6da3cc2283
11 files changed
+432
-30
No files matched your search
Executable
+63
@@ -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
|
||||
Reference in new issue
Block a user