← Zurück

Cron Backup Script Template

Cron Backup Script – Template

Vorlage für ein robustes Backup-Script mit Logging, Fehlerbehandlung und Rotation.


Basis-Template

#!/bin/bash
#
# Backup Script für Cron
# Crontab: 0 3 * * * /home/user/scripts/backup.sh
#

set -e  # Bei Fehler abbrechen

# === KONFIGURATION ===
BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup.log"
RETENTION_DAYS=7
DATE=$(date +%Y-%m-%d_%H-%M)
BACKUP_NAME="backup_${DATE}"

# === FUNKTIONEN ===
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

cleanup() {
    if [ $? -ne 0 ]; then
        log "FEHLER: Backup fehlgeschlagen!"
    fi
    # Lock-Datei entfernen
    rm -f /tmp/backup.lock
}
trap cleanup EXIT

# === LOCK (verhindert parallele Ausführung) ===
LOCKFILE=/tmp/backup.lock
if [ -f "$LOCKFILE" ]; then
    log "WARNUNG: Backup läuft bereits"
    exit 1
fi
touch "$LOCKFILE"

# === BACKUP STARTEN ===
log "=== Backup gestartet ==="

# Backup-Verzeichnis erstellen
mkdir -p "$BACKUP_DIR/$BACKUP_NAME"

# Hier Backup-Befehle einfügen:
# tar -czf "$BACKUP_DIR/$BACKUP_NAME/home.tar.gz" /home/
# mysqldump -u root --all-databases > "$BACKUP_DIR/$BACKUP_NAME/mysql.sql"

log "Backup erstellt: $BACKUP_NAME"

# === ALTE BACKUPS LÖSCHEN ===
find "$BACKUP_DIR" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \; 2>/dev/null
log "Alte Backups (>$RETENTION_DAYS Tage) gelöscht"

log "=== Backup beendet ==="

Vollständiges Beispiel

#!/bin/bash
#
# Vollständiges Server-Backup
# Sichert: Konfigurationen, Websites, Datenbanken
# Crontab: 0 3 * * * /usr/local/bin/server-backup.sh
#

set -euo pipefail

# === KONFIGURATION ===
BACKUP_ROOT="/backup"
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="$BACKUP_ROOT/$DATE"
LOG="/var/log/backup.log"
RETENTION=7

# Was sichern?
BACKUP_DIRS="/etc /home /var/www"
MYSQL_USER="backup"
MYSQL_PASS="geheim"

# Benachrichtigung
MAIL_TO="admin@example.com"

# === FUNKTIONEN ===
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"
}

error_exit() {
    log "FEHLER: $1"
    echo "Backup fehlgeschlagen: $1" | mail -s "Backup FEHLER" "$MAIL_TO"
    exit 1
}

# === PRE-CHECKS ===
# Lock
LOCK="/var/run/backup.lock"
exec 200>"$LOCK"
flock -n 200 || error_exit "Backup läuft bereits"

# Speicherplatz prüfen (mind. 10GB frei)
FREE=$(df "$BACKUP_ROOT" | tail -1 | awk '{print $4}')
[ "$FREE" -lt 10485760 ] && error_exit "Nicht genug Speicherplatz"

# === BACKUP STARTEN ===
log "=========================================="
log "Backup gestartet"
log "=========================================="

mkdir -p "$BACKUP_DIR"

# --- Dateien sichern ---
log "Sichere Verzeichnisse..."
for DIR in $BACKUP_DIRS; do
    NAME=$(echo "$DIR" | tr '/' '_')
    tar -czf "$BACKUP_DIR/${NAME}.tar.gz" "$DIR" 2>/dev/null || true
    log "  $DIR -> ${NAME}.tar.gz"
done

# --- MySQL sichern ---
log "Sichere MySQL-Datenbanken..."
DATABASES=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|sys)")
for DB in $DATABASES; do
    mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASS" --single-transaction "$DB" | gzip > "$BACKUP_DIR/mysql_${DB}.sql.gz"
    log "  Datenbank: $DB"
done

# --- Paketliste sichern ---
log "Sichere Paketliste..."
dpkg --get-selections > "$BACKUP_DIR/packages.list"

# --- Crontabs sichern ---
log "Sichere Crontabs..."
for USER in $(cut -f1 -d: /etc/passwd); do
    crontab -l -u "$USER" > "$BACKUP_DIR/crontab_${USER}.txt" 2>/dev/null || true
done

# === ROTATION ===
log "Lösche alte Backups (>$RETENTION Tage)..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +$RETENTION -exec rm -rf {} \;

# === ZUSAMMENFASSUNG ===
SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
log "Backup abgeschlossen: $BACKUP_DIR ($SIZE)"
log "=========================================="

# Erfolgs-Mail (optional)
# echo "Backup erfolgreich: $SIZE" | mail -s "Backup OK" "$MAIL_TO"

exit 0

Mit Remote-Sync (rsync/rclone)

#!/bin/bash
# Nach lokalem Backup: Sync zu Remote-Server

# Lokales Backup (wie oben)
# ...

# Zu Remote-Server synchronisieren
log "Synchronisiere zu Remote..."
rsync -avz --delete "$BACKUP_ROOT/" user@remote:/backup/server1/

# Oder zu Cloud (rclone)
# rclone sync "$BACKUP_ROOT" gdrive:backups/server1

Crontab-Einträge

# Tägliches Backup um 3:00
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup-cron.log 2>&1

# Wöchentliches Vollbackup Sonntag 2:00
0 2 * * 0 /usr/local/bin/full-backup.sh >> /var/log/backup-cron.log 2>&1

# Stündliche Datenbank-Snapshots
0 * * * * /usr/local/bin/db-snapshot.sh > /dev/null 2>&1

Monitoring-Script

#!/bin/bash
# Prüft ob Backup erfolgreich war

BACKUP_DIR="/backup"
MAX_AGE=26  # Stunden

LATEST=$(find "$BACKUP_DIR" -maxdepth 1 -type d -mmin -$((MAX_AGE * 60)) | wc -l)

if [ "$LATEST" -eq 0 ]; then
    echo "WARNUNG: Kein Backup in den letzten $MAX_AGE Stunden!" | \
    mail -s "Backup-Warnung" admin@example.com
fi