Backup DB-Dump + rclone sync, cron-ready

Einrichten:

Bash
chmod +x wp-backup.sh
crontab -e

Cron-Eintrag (täglich 02:00):

Bash
0 2 * * * /pfad/zu/wp-backup.sh

Restore einer Site:

Bash
# Files
rclone sync swissbackup:kunde1.ch/files /var/www/html/kunde1.ch

# DB
rclone copy swissbackup:kunde1.ch/db /tmp/restore/
gunzip -c /tmp/restore/kunde1.ch_2026-05-13.sql.gz | mysql -u dbuser -p wp_kunde1

Anpassen musst du:

  • SITES_BASE — dein Webroot
  • RCLONE_REMOTE — muss mit deinem rclone.conf-Namen übereinstimmen

Skript

Bash
#!/bin/bash
# ============================================================
# wp-backup.sh — WordPress Backup → Infomaniak Swiss Backup
# Anpassen: SITES_BASE, RCLONE_REMOTE
# DB-Credentials werden automatisch aus wp-config.php gelesen
# ============================================================

# --- Konfiguration ------------------------------------------
SITES_BASE="/var/www/html"        # Basis-Pfad aller Sites
BACKUP_TMP="/tmp/wp-backups"      # Temp-Ordner für DB-Dumps
RCLONE_REMOTE="swissbackup"       # Name aus rclone.conf
KEEP_DAYS=7                       # Lokale Dumps aufbewahren
LOG="/var/log/wp-backup.log"

# --- Hilfsfunktion: Wert aus wp-config.php lesen ------------
wp_config_get() {
  local file="$1" key="$2"
  grep "define.*'${key}'" "$file" | sed "s/.*define.*'${key}'.*'\(.*\)'.*/\1/"
}

# --- Script -------------------------------------------------
mkdir -p "$BACKUP_TMP"
DATE=$(date +%Y-%m-%d)

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

# Alle Unterordner in SITES_BASE mit wp-config.php durchsuchen
for SITE_PATH in "$SITES_BASE"/*/; do
  SITE=$(basename "$SITE_PATH")
  WP_CONFIG="$SITE_PATH/wp-config.php"
  DUMP_FILE="$BACKUP_TMP/${SITE}_${DATE}.sql.gz"

  # Kein WordPress → überspringen
  [ -f "$WP_CONFIG" ] || continue

  # Credentials aus wp-config.php lesen
  DB_NAME=$(wp_config_get "$WP_CONFIG" "DB_NAME")
  DB_USER=$(wp_config_get "$WP_CONFIG" "DB_USER")
  DB_PASS=$(wp_config_get "$WP_CONFIG" "DB_PASSWORD")
  DB_HOST=$(wp_config_get "$WP_CONFIG" "DB_HOST")
  DB_HOST="${DB_HOST:-localhost}"

  log "▶ $SITE (DB: $DB_NAME @ $DB_HOST)"

  # DB-Dump
  if mysqldump -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$DUMP_FILE"; then
    log "  ✓ DB-Dump: $DUMP_FILE"
  else
    log "  ✗ DB-Dump FEHLER — überspringe $SITE"
    continue
  fi

  # WP-Files sync
  if rclone sync "$SITE_PATH" "$RCLONE_REMOTE:$SITE/files" \
    --exclude "*.log" \
    --exclude "wp-content/cache/**" \
    --exclude "wp-content/uploads/backup-guard*" \
    2>> "$LOG"; then
    log "  ✓ Files sync"
  else
    log "  ✗ Files sync FEHLER"
  fi

  # DB-Dump hochladen
  if rclone copy "$DUMP_FILE" "$RCLONE_REMOTE:$SITE/db" 2>> "$LOG"; then
    log "  ✓ DB Upload"
  else
    log "  ✗ DB Upload FEHLER"
  fi

done

# Alte lokale Dumps aufräumen
find "$BACKUP_TMP" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
log "✓ Backup abgeschlossen"