Files
LehrerApp/docker/backup.sh
T
adminandClaude Sonnet 5 cdac335ad1 fix: Server-Daten in Named Volume statt Bind-Mount
./data war ein Bind-Mount relativ zum Git-Checkout - bei Dokploy wird
das Repo pro Deploy frisch geklont, ein per CLI angelegter Nutzer war
nach einem reinen Routing-Redeploy spurlos verschwunden. Betraf nicht
nur Nutzer, sondern denselben Api:DataPath für Ereignis-Log/Snapshots/
Anhänge - also jeden Server-Datenbestand bei jedem Redeploy.

- docker-compose.yml: Named Volume "api-data" statt Bind-Mount, lebt
  unabhängig vom Checkout im Docker-Daemon.
- backup.sh: auf volume-basiertes Backup umgeschrieben (Alpine-
  Hilfscontainer statt direktem Host-Pfad).
- docker/README.md, TODO.md 10.2.4: Vorfall dokumentiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 00:02:56 +02:00

41 lines
1.8 KiB
Bash
Executable File

#!/bin/sh
# Sichert das Docker-Volume "api-data" (Ereignis-Logs, Snapshots, Anhänge, Nutzer) als
# komprimiertes Tar-Archiv. Läuft über einen kurzlebigen Alpine-Container mit Zugriff auf das
# Volume - kein direkter Host-Pfad, seit das Volume kein Bind-Mount mehr ist (siehe
# docker-compose.yml: Dokploy-Redeploys klonen das Repo neu, ein Bind-Mount relativ zum
# Checkout würde dabei geleert, siehe TODO.md 10.2.4).
#
# Der volle Docker-Volume-Name ist "<compose-projektname>_api-data" - bei einem lokalen
# "cd docker && docker compose up" ist das "docker_api-data" (Default unten), bei Dokploy der
# App-Slug, z.B. "lehrerapp-syncserver-xyz_api-data". Im Zweifel prüfen mit:
# docker volume ls | grep api-data
# und den echten Namen per LEHRERAPP_DATA_VOLUME übergeben:
# LEHRERAPP_DATA_VOLUME=lehrerapp-syncserver-xyz_api-data /pfad/zu/docker/backup.sh
#
# Aufruf z.B. per Cron:
# 0 3 * * * LEHRERAPP_DATA_VOLUME=... /pfad/zu/docker/backup.sh >> /pfad/zu/docker/backup.log 2>&1
set -eu
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKUP_DIR="$SCRIPT_DIR/backups"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
KEEP_DAYS=30
VOLUME_NAME="${LEHRERAPP_DATA_VOLUME:-docker_api-data}"
if ! docker volume inspect "$VOLUME_NAME" >/dev/null 2>&1; then
echo "Docker-Volume '$VOLUME_NAME' nicht gefunden (docker volume ls | grep api-data) - nichts zu sichern." >&2
exit 1
fi
mkdir -p "$BACKUP_DIR"
docker run --rm \
-v "$VOLUME_NAME":/data:ro \
-v "$BACKUP_DIR":/backup \
alpine:3 \
tar -czf "/backup/lehrerapp-data-$TIMESTAMP.tar.gz" -C /data .
# Alte Backups jenseits von KEEP_DAYS aufräumen, damit das Verzeichnis nicht unbegrenzt wächst.
find "$BACKUP_DIR" -name 'lehrerapp-data-*.tar.gz' -mtime "+$KEEP_DAYS" -delete
echo "Backup erstellt: $BACKUP_DIR/lehrerapp-data-$TIMESTAMP.tar.gz"