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