2026-04-25 21:00:52 +02:00
|
|
|
#!/bin/bash
|
|
|
|
|
# Daily backup via Pythons sqlite3.backup() — atomar, async-DB-safe,
|
|
|
|
|
# kein sqlite3-CLI im Container vorausgesetzt.
|
2026-05-10 12:49:15 +02:00
|
|
|
#
|
|
|
|
|
# Usage:
|
|
|
|
|
# ./scripts/backup-db.sh # Default: prod
|
|
|
|
|
# ./scripts/backup-db.sh gwoe-antragspruefer-dev # dev
|
|
|
|
|
#
|
|
|
|
|
# Auto-Detect: BACKUP_DIR wird aus dem Skript-Pfad abgeleitet
|
|
|
|
|
# (parent-of-scripts/.../backups), damit die gleiche Datei via
|
|
|
|
|
# `git pull` auf prod und dev funktioniert ohne pfad-spezifisches Hardcoding.
|
2026-04-25 21:00:52 +02:00
|
|
|
set -euo pipefail
|
2026-05-10 12:49:15 +02:00
|
|
|
|
|
|
|
|
CONTAINER="${1:-gwoe-antragspruefer}"
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
|
BACKUP_DIR="${BACKUP_DIR:-$PROJECT_DIR/backups}"
|
2026-04-25 21:00:52 +02:00
|
|
|
TS=$(date +%Y%m%d-%H%M%S)
|
2026-05-10 12:49:15 +02:00
|
|
|
|
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
|
|
|
|
|
|
docker exec "$CONTAINER" python -c "
|
2026-04-25 21:00:52 +02:00
|
|
|
import sqlite3
|
|
|
|
|
src = sqlite3.connect(\"/app/data/gwoe-antraege.db\")
|
|
|
|
|
dst = sqlite3.connect(\"/tmp/db-backup.db\")
|
|
|
|
|
src.backup(dst); dst.close(); src.close()
|
|
|
|
|
" 2>&1
|
2026-05-10 12:49:15 +02:00
|
|
|
|
|
|
|
|
docker cp "$CONTAINER:/tmp/db-backup.db" "$BACKUP_DIR/gwoe-antraege-$TS.db"
|
|
|
|
|
docker exec "$CONTAINER" rm /tmp/db-backup.db
|
|
|
|
|
gzip -9 "$BACKUP_DIR/gwoe-antraege-$TS.db"
|
|
|
|
|
|
|
|
|
|
# Rotation: 30 Tage, plus Monatsanker (Tag 01) langfristig
|
|
|
|
|
find "$BACKUP_DIR" -name "gwoe-antraege-*.db.gz" -mtime +30 \
|
2026-04-25 21:00:52 +02:00
|
|
|
! -name "gwoe-antraege-*01-*.db.gz" -delete 2>/dev/null || true
|
2026-05-10 12:49:15 +02:00
|
|
|
|
2026-04-25 21:00:52 +02:00
|
|
|
echo "$(date -Iseconds) backup ok: $BACKUP_DIR/gwoe-antraege-$TS.db.gz"
|