Files
florian.wildeandClaude Opus 5 409a02561d feat(deploy): Wiederherstellung proben und Skript dafuer (#045)
Einer der vier Punkte bis 1.0.0: eine Sicherung einmal wirklich
zurueckspielen. Mit einem eigenen Stapel durchgespielt - Datenstand
festgehalten, Marke gesetzt, PDF abgelegt, gesichert, alle Volumes
zerstoert, zurueckgespielt. Datenbank, PDF und Anmeldung waren zurueck.

Zwei Luecken kamen erst dabei heraus:

1. Ohne --clean liess sich die Sicherung nur in eine LEERE Datenbank
   zurueckspielen - im Ernstfall also gerade nicht. Jetzt
   pg_dump --clean --if-exists, gegen eine Datenbank mit Daten geprueft.
2. Fuer die hochgeladenen PDFs gab es keinen beschriebenen Weg zurueck.

deploy/restore.sh haelt die Dienste an, spielt Datenbank und PDFs zurueck,
startet wieder und prueft die Erreichbarkeit. Die .env bleibt unangetastet:
Sie traegt APP_SECRET, und ein falscher Wert dort macht gespeicherte
Zugangsdaten unlesbar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-10 19:31:35 +02:00

74 lines
2.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Sichert Datenbank, hochgeladene PDFs und die Konfiguration von ProxLedger.
# Erkennt selbst, ob die Installation mit Docker oder als Dienst im Container läuft.
#
# ./backup.sh /pfad/zum/sicherungsordner
#
# Für regelmäßige Sicherungen in die Crontab eintragen, z. B. täglich um 02:30 Uhr:
# 30 2 * * * /opt/proxledger/deploy/backup.sh /var/backups/proxledger
set -o errexit
set -o nounset
set -o pipefail
ZIEL="${1:-/var/backups/proxledger}"
AUFBEWAHRUNG_TAGE="${AUFBEWAHRUNG_TAGE:-30}"
STAND=$(date +%Y%m%d-%H%M%S)
VERZEICHNIS="${COMPOSE_VERZEICHNIS:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
mkdir -p "$ZIEL"
cd "$VERZEICHNIS"
# Siehe deploy/update.sh – der Dienst ist das eindeutigere Merkmal.
if systemctl cat proxledger.service >/dev/null 2>&1; then
ART="dienst"
else
ART="docker"
fi
echo "Sichere ProxLedger (${ART}) nach ${ZIEL} …"
if [ "$ART" = "docker" ]; then
echo "Sichere Datenbank …"
docker compose exec -T postgres pg_dump --clean --if-exists \
-U "${POSTGRES_USER:-proxledger}" "${POSTGRES_DB:-proxledger}" \
| gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
echo "Sichere hochgeladene Dateien …"
docker compose run --rm -T --entrypoint tar web -czf - /data/uploads > "${ZIEL}/uploads-${STAND}.tar.gz" 2>/dev/null || true
else
# DATABASE_URL steht in der .env; pg_dump versteht sie direkt.
# shellcheck disable=SC1091
set -o allexport
. ./.env
set +o allexport
[ -n "${DATABASE_URL:-}" ] || {
echo "DATABASE_URL fehlt in der .env – ohne sie keine Sicherung." >&2
exit 1
}
echo "Sichere Datenbank …"
pg_dump --clean --if-exists "$DATABASE_URL" | gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
echo "Sichere hochgeladene Dateien …"
UPLOADS="${UPLOAD_DIR:-${VERZEICHNIS}/data/uploads}"
if [ -d "$UPLOADS" ]; then
tar -czf "${ZIEL}/uploads-${STAND}.tar.gz" -C "$(dirname "$UPLOADS")" "$(basename "$UPLOADS")"
else
echo " (kein Upload-Verzeichnis unter ${UPLOADS})"
fi
fi
echo "Sichere Konfiguration …"
cp .env "${ZIEL}/env-${STAND}.txt"
chmod 600 "${ZIEL}/env-${STAND}.txt"
echo "Entferne Sicherungen älter als ${AUFBEWAHRUNG_TAGE} Tage …"
find "$ZIEL" -maxdepth 1 -name "*-*.sql.gz" -mtime "+${AUFBEWAHRUNG_TAGE}" -delete
find "$ZIEL" -maxdepth 1 -name "*-*.tar.gz" -mtime "+${AUFBEWAHRUNG_TAGE}" -delete
find "$ZIEL" -maxdepth 1 -name "env-*.txt" -mtime "+${AUFBEWAHRUNG_TAGE}" -delete
echo "Fertig: ${ZIEL}"
ls -lh "$ZIEL" | tail -n 5