145 lines
4.0 KiB
Bash
Executable File
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."
|