Files
logbuch/backup_db.sh
T

145 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Tägliches MySQL-Backup für das Logbuch-Projekt.
#
# Verwendung:
# ./backup_db.sh
# DB_ROOT_PASS=... DB_NAME=... ./backup_db.sh
# ./backup_db.sh --days 14 --backup-dir /var/backups/logbuch
#
# Installiert keine Abhängigkeiten. Nutzt den laufenden Container mit dem Namen logbuch_mysql.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_DIR_DEFAULT="$SCRIPT_DIR/DB_BACKUP"
CONTAINER_DEFAULT="logbuch_mysql"
KEEP_DAYS_DEFAULT=7
ROOT_PASS="${DB_ROOT_PASS:-${MYSQL_ROOT_PASSWORD:-}}"
DB_NAME="${DB_NAME:-${MYSQL_DATABASE:-}}"
BACKUP_DIR="$BACKUP_DIR_DEFAULT"
CONTAINER="$CONTAINER_DEFAULT"
KEEP_DAYS="$KEEP_DAYS_DEFAULT"
REMOTE=""
REMOTE_RETENTION=""
usage() {
cat <<EOF
Usage: $0 [options]
Options:
--backup-dir DIR Backup-Verzeichnis (default: $BACKUP_DIR_DEFAULT)
--container NAME MySQL-Container-Name (default: $CONTAINER_DEFAULT)
--days N Aufbewahrungszeitraum in Tagen (default: $KEEP_DAYS_DEFAULT)
--db-name NAME Datenbankname (default: DB_NAME oder MYSQL_DATABASE env)
--root-pass PASS MySQL root Passwort (default: DB_ROOT_PASS oder MYSQL_ROOT_PASSWORD env)
--remote user@host:/path Optional: kopiere Backup per scp auf Remote-Host
--remote-retention N Optional: Aufbewahrungstage auf Remote (default: same as --days)
-h, --help Diese Hilfe anzeigen
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--backup-dir)
BACKUP_DIR="$2"
shift 2
;;
--container)
CONTAINER="$2"
shift 2
;;
--days)
KEEP_DAYS="$2"
shift 2
;;
--db-name)
DB_NAME="$2"
shift 2
;;
--root-pass)
ROOT_PASS="$2"
shift 2
;;
--remote)
REMOTE="$2"
shift 2
;;
--remote-retention)
REMOTE_RETENTION="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unbekannte Option: $1" >&2
usage
exit 1
;;
esac
done
if [[ -z "$ROOT_PASS" ]]; then
echo "Fehler: MySQL root Passwort ist nicht gesetzt. Setze DB_ROOT_PASS oder MYSQL_ROOT_PASSWORD." >&2
exit 1
fi
if [[ -z "$DB_NAME" ]]; then
echo "Fehler: Datenbankname ist nicht gesetzt. Setze DB_NAME oder MYSQL_DATABASE." >&2
exit 1
fi
mkdir -p "$BACKUP_DIR"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_$TIMESTAMP.sql.gz"
echo "Erstelle Backup: $BACKUP_FILE"
docker exec "$CONTAINER" mysqldump --single-transaction --quick --lock-tables=false \
--triggers --routines --events --set-gtid-purged=OFF -uroot -p"$ROOT_PASS" "$DB_NAME" | gzip > "$BACKUP_FILE"
if [[ ! -s "$BACKUP_FILE" ]]; then
echo "Fehler: Backup konnte nicht erstellt werden." >&2
exit 1
fi
echo "Backup erfolgreich erstellt: $BACKUP_FILE"
# Optional: upload to remote host (format: user@host:/path)
if [[ -n "$REMOTE" ]]; then
echo "Upload nach Remote: $REMOTE"
if [[ -z "$REMOTE_RETENTION" ]]; then
REMOTE_RETENTION="$KEEP_DAYS"
fi
if [[ "$REMOTE" == *":"* ]]; then
REMOTE_HOSTPART="${REMOTE%%:*}"
REMOTE_PATH="${REMOTE#*:}"
if [[ -z "$REMOTE_PATH" ]]; then
REMOTE_PATH="."
fi
# Verzeichnis auf Remote anlegen, dann Datei kopieren
ssh -o BatchMode=yes "$REMOTE_HOSTPART" "mkdir -p \"$REMOTE_PATH\""
if ! scp -q "$BACKUP_FILE" "${REMOTE_HOSTPART}:${REMOTE_PATH}/"; then
echo "Warnung: Hochladen nach Remote fehlgeschlagen." >&2
else
echo "Upload erfolgreich."
echo "Auf Remote $REMOTE_HOSTPART: entferne Backups älter als $REMOTE_RETENTION Tage in $REMOTE_PATH"
ssh -o BatchMode=yes "$REMOTE_HOSTPART" "find \"$REMOTE_PATH\" -maxdepth 1 -type f -name '${DB_NAME}_*.sql.gz' -mtime +$REMOTE_RETENTION -print -delete" || true
fi
else
if ! scp -q "$BACKUP_FILE" "$REMOTE"; then
echo "Warnung: Hochladen nach Remote fehlgeschlagen." >&2
else
echo "Upload erfolgreich."
fi
fi
fi
echo "Lösche Backups älter als $KEEP_DAYS Tage im Verzeichnis $BACKUP_DIR"
find "$BACKUP_DIR" -maxdepth 1 -type f -name "${DB_NAME}_*.sql.gz" -mtime +"$KEEP_DAYS" -print -delete || true
echo "Fertig."