#!/bin/bash # Steuerkram – Restore-Script # Spielt ein Backup-Paar (DB + Uploads) ein und führt anschließend alle # ausstehenden Migrationen aus. # # Usage: # ./scripts/restore.sh # neuestes vollständiges Backup # ./scripts/restore.sh 20260517_134945 # bestimmten Timestamp set -eo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" BACKUP_DIR="$PROJECT_DIR/backups" COMPOSE="docker compose -f $PROJECT_DIR/docker-compose.yml --project-directory $PROJECT_DIR" # --- Timestamp ermitteln --- if [ -n "$1" ]; then TS="$1" else # Neuesten Timestamp finden, für den BEIDE Dateien existieren TS="" for DB_FILE in $(ls -t "$BACKUP_DIR"/steuerkram_db_????????_??????.sql 2>/dev/null); do CANDIDATE=$(basename "$DB_FILE" .sql | sed 's/steuerkram_db_//') UPL_FILE="$BACKUP_DIR/steuerkram_uploads_${CANDIDATE}.tar.gz" if [ -f "$UPL_FILE" ]; then TS="$CANDIDATE" break fi done fi DB_FILE="$BACKUP_DIR/steuerkram_db_${TS}.sql" UPL_FILE="$BACKUP_DIR/steuerkram_uploads_${TS}.tar.gz" # --- Dateien prüfen --- if [ -z "$TS" ]; then echo "FEHLER: Kein vollständiges Backup-Paar (DB + Uploads) gefunden." >&2 exit 1 fi if [ ! -f "$DB_FILE" ]; then echo "FEHLER: DB-Backup nicht gefunden: $DB_FILE" >&2 exit 1 fi if [ ! -f "$UPL_FILE" ]; then echo "FEHLER: Uploads-Backup nicht gefunden: $UPL_FILE" >&2 exit 1 fi echo "========================================" echo " Steuerkram Restore – $TS" echo "========================================" echo " DB: $DB_FILE" echo " Uploads: $UPL_FILE" echo "" # --- Sicherheitsabfrage --- read -r -p "Vorhandene Datenbank und Uploads werden ÜBERSCHRIEBEN. Fortfahren? [j/N] " CONFIRM if [[ ! "$CONFIRM" =~ ^[jJyY]$ ]]; then echo "Abgebrochen." exit 0 fi # --- Container-Status prüfen --- if ! $COMPOSE ps --status running db | grep -q "db"; then echo "FEHLER: DB-Container läuft nicht. Bitte erst 'docker compose up -d' ausführen." >&2 exit 1 fi if ! $COMPOSE ps --status running web | grep -q "web"; then echo "FEHLER: Web-Container läuft nicht." >&2 exit 1 fi # --- 1. Datenbank einspielen --- echo "" echo "[1/3] Datenbank importieren..." $COMPOSE exec -T db mariadb -u root -prootpass steuerkram < "$DB_FILE" echo " OK" # --- 2. Nutzdateien einspielen --- # Das Archiv wird zunächst ausgepackt und dann normalisiert. Unterstützt werden # alle Ablagen, die im Lauf der Zeit im Einsatz waren: # belege/, logo/ aktuelle Struktur # legacy-uploads/ gemeinsame Ablage vor der Trennung # uploads/ Web-Root-Ablage vor Fix #116 # In allen Fällen landet ein Unterordner logo/ in data/logo, alles Übrige in # data/belege. echo "[2/3] Belege und Logo entpacken..." $COMPOSE exec -T web sh -c ' set -e STAGE=/tmp/restore-stage rm -rf "$STAGE" && mkdir -p "$STAGE" cat > /tmp/restore.tar.gz tar -xzf /tmp/restore.tar.gz -C "$STAGE" rm -f /tmp/restore.tar.gz BELEGE=/var/www/html/data/belege LOGO=/var/www/html/data/logo mkdir -p "$BELEGE" "$LOGO" RESTORED_B=0 RESTORED_L=0 # Aktuelle Struktur if [ -d "$STAGE/belege" ]; then cp -a "$STAGE/belege/." "$BELEGE/" && RESTORED_B=1 fi if [ -d "$STAGE/logo" ]; then cp -a "$STAGE/logo/." "$LOGO/" && RESTORED_L=1 fi # Ältere Sammelablagen auf die neue Struktur verteilen for old in legacy-uploads uploads; do [ -d "$STAGE/$old" ] || continue echo " Älteres Archivformat \"$old/\" erkannt – wird verteilt." if [ -d "$STAGE/$old/logo" ]; then cp -a "$STAGE/$old/logo/." "$LOGO/" && RESTORED_L=1 rm -rf "$STAGE/$old/logo" fi if [ -n "$(ls -A "$STAGE/$old" 2>/dev/null)" ]; then cp -a "$STAGE/$old/." "$BELEGE/" && RESTORED_B=1 fi done rm -rf "$STAGE" chown -R www-data:www-data "$BELEGE" "$LOGO" echo " Belege: $(find "$BELEGE" -type f | wc -l) Datei(en), Logo: $(find "$LOGO" -type f | wc -l) Datei(en)" if [ "$RESTORED_B" = "0" ] && [ "$RESTORED_L" = "0" ]; then echo " WARNUNG: Das Archiv enthielt keine bekannten Verzeichnisse!" >&2 fi ' < "$UPL_FILE" echo " OK" # --- 3. Migrationen --- echo "[3/3] Migrationen prüfen und einspielen..." MIGRATE_OUT=$($COMPOSE exec -T web php scripts/migrate.php 2>&1) echo "$MIGRATE_OUT" | sed 's/^/ /' if echo "$MIGRATE_OUT" | grep -q "FEHLER"; then echo "" echo "WARNUNG: Mindestens eine Migration ist fehlgeschlagen!" >&2 exit 1 fi echo "" echo "========================================" echo " Restore abgeschlossen." echo "========================================"