Ein WordPress-Backup ist Pflicht für jeden Website-Betreiber. Mit WP-CLI und Bash-Skripten automatisieren Sie die Sicherung und stellen im Notfall schnell wieder her.

Was muss gesichert werden?

WordPress-Komponenten

WordPress-Installation:
├── Datenbank (MySQL/MariaDB)
│   ├── Posts und Seiten
│   ├── Kommentare
│   ├── Benutzer
│   └── Optionen/Einstellungen
└── Dateien
    ├── wp-content/
    │   ├── themes/
    │   ├── plugins/
    │   └── uploads/
    └── wp-config.php

Wichtigste Verzeichnisse

| Verzeichnis | Inhalt | Priorität | |-------------|--------|-----------| | wp-content/uploads | Medien | Sehr hoch | | wp-content/themes | Themes | Hoch | | wp-content/plugins | Plugins | Hoch | | wp-config.php | Konfiguration | Sehr hoch |

WP-CLI installieren

Installation

# WP-CLI herunterladen
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

# Ausführbar machen
chmod +x wp-cli.phar

# Global verfügbar machen
sudo mv wp-cli.phar /usr/local/bin/wp

# Installation prüfen
wp --info

WP-CLI für Webserver-User

# Als www-data ausführen
sudo -u www-data wp --info --path=/var/www/wordpress

Datenbank sichern

Mit WP-CLI

# Einfacher DB-Export
cd /var/www/wordpress
wp db export backup.sql

# Mit Kompression
wp db export - | gzip > backup-$(date +%Y%m%d).sql.gz

# Mit Zeitstempel
wp db export backup-$(date +%Y%m%d-%H%M%S).sql

Direkt mit mysqldump

# Datenbank-Zugangsdaten aus wp-config.php
DB_NAME=$(grep "DB_NAME" wp-config.php | cut -d "'" -f 4)
DB_USER=$(grep "DB_USER" wp-config.php | cut -d "'" -f 4)
DB_PASS=$(grep "DB_PASSWORD" wp-config.php | cut -d "'" -f 4)

# Backup erstellen
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" > backup.sql

Optimierte Optionen

# Mit erweiterten Optionen
mysqldump -u "$DB_USER" -p"$DB_PASS" \
    --single-transaction \
    --quick \
    --lock-tables=false \
    --routines \
    --triggers \
    "$DB_NAME" | gzip > backup.sql.gz

Dateien sichern

Mit tar

# Komplettes wp-content sichern
tar -czvf wp-content-$(date +%Y%m%d).tar.gz /var/www/wordpress/wp-content/

# wp-config.php separat
cp /var/www/wordpress/wp-config.php wp-config-backup-$(date +%Y%m%d).php

Mit rsync

# Inkrementelles Backup
rsync -avz --delete \
    /var/www/wordpress/wp-content/ \
    /backup/wordpress/wp-content/

# Mit Exclude
rsync -avz --delete \
    --exclude='cache/' \
    --exclude='*.log' \
    /var/www/wordpress/wp-content/ \
    /backup/wordpress/wp-content/

Komplettes Backup-Skript

Basis-Skript

#!/bin/bash
# wordpress-backup.sh - Vollständiges WordPress-Backup

# Konfiguration
WP_PATH="/var/www/wordpress"
BACKUP_DIR="/backup/wordpress"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_NAME="wordpress-$DATE"
KEEP_DAYS=30

# Verzeichnis erstellen
mkdir -p "$BACKUP_DIR"

# Als www-data wechseln
cd "$WP_PATH"

# Datenbank sichern
echo "Sichere Datenbank..."
sudo -u www-data wp db export - | gzip > "$BACKUP_DIR/$BACKUP_NAME-db.sql.gz"

# Dateien sichern
echo "Sichere Dateien..."
tar -czf "$BACKUP_DIR/$BACKUP_NAME-files.tar.gz" \
    wp-content/ \
    wp-config.php

# Alte Backups löschen
echo "Lösche alte Backups..."
find "$BACKUP_DIR" -type f -mtime +$KEEP_DAYS -delete

# Statistik
echo "Backup abgeschlossen:"
ls -lh "$BACKUP_DIR/$BACKUP_NAME"*

echo "Fertig!"

Erweitertes Skript mit Logging

#!/bin/bash
# wordpress-backup-advanced.sh

set -euo pipefail

# Konfiguration
WP_PATH="/var/www/wordpress"
BACKUP_DIR="/backup/wordpress"
LOG_FILE="/var/log/wordpress-backup.log"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_NAME="wordpress-$DATE"
KEEP_DAYS=30
MAIL_TO="admin@example.com"

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

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

# Platz prüfen
check_disk_space() {
    local required=5000000  # 5 GB in KB
    local available=$(df "$BACKUP_DIR" | tail -1 | awk '{print $4}')

    if [ "$available" -lt "$required" ]; then
        error_exit "Nicht genug Speicherplatz: ${available}KB verfügbar"
    fi
}

# Start
log "=== Backup gestartet ==="

# Prüfungen
check_disk_space
mkdir -p "$BACKUP_DIR"
cd "$WP_PATH" || error_exit "WordPress-Verzeichnis nicht gefunden"

# WordPress-Installation prüfen
sudo -u www-data wp core is-installed 2>/dev/null || error_exit "Keine WordPress-Installation gefunden"

# Maintenance-Mode aktivieren (optional)
log "Aktiviere Maintenance-Mode..."
sudo -u www-data wp maintenance-mode activate 2>/dev/null || true

# Datenbank sichern
log "Sichere Datenbank..."
if ! sudo -u www-data wp db export - 2>/dev/null | gzip > "$BACKUP_DIR/$BACKUP_NAME-db.sql.gz"; then
    sudo -u www-data wp maintenance-mode deactivate 2>/dev/null || true
    error_exit "Datenbank-Backup fehlgeschlagen"
fi

DB_SIZE=$(ls -lh "$BACKUP_DIR/$BACKUP_NAME-db.sql.gz" | awk '{print $5}')
log "Datenbank gesichert: $DB_SIZE"

# Dateien sichern
log "Sichere Dateien..."
if ! tar -czf "$BACKUP_DIR/$BACKUP_NAME-files.tar.gz" wp-content/ wp-config.php 2>/dev/null; then
    sudo -u www-data wp maintenance-mode deactivate 2>/dev/null || true
    error_exit "Datei-Backup fehlgeschlagen"
fi

FILES_SIZE=$(ls -lh "$BACKUP_DIR/$BACKUP_NAME-files.tar.gz" | awk '{print $5}')
log "Dateien gesichert: $FILES_SIZE"

# Maintenance-Mode deaktivieren
log "Deaktiviere Maintenance-Mode..."
sudo -u www-data wp maintenance-mode deactivate 2>/dev/null || true

# Checksummen erstellen
log "Erstelle Checksummen..."
cd "$BACKUP_DIR"
sha256sum "$BACKUP_NAME"* > "$BACKUP_NAME.sha256"

# Alte Backups löschen
log "Lösche Backups älter als $KEEP_DAYS Tage..."
DELETED=$(find "$BACKUP_DIR" -type f -mtime +$KEEP_DAYS -delete -print | wc -l)
log "Gelöschte Dateien: $DELETED"

# Zusammenfassung
log "=== Backup abgeschlossen ==="
log "Datenbank: $DB_SIZE"
log "Dateien: $FILES_SIZE"

# Erfolgs-Mail (optional)
# echo "WordPress Backup erfolgreich: DB=$DB_SIZE, Files=$FILES_SIZE" | mail -s "Backup OK" "$MAIL_TO"

exit 0

Skript einrichten

# Ausführbar machen
chmod +x /usr/local/bin/wordpress-backup.sh

# Testen
/usr/local/bin/wordpress-backup.sh

Automatisierung mit Cron

Tägliches Backup

# Crontab bearbeiten
crontab -e

# Täglich um 2:00 Uhr
0 2 * * * /usr/local/bin/wordpress-backup.sh >> /var/log/wp-backup.log 2>&1

Verschiedene Intervalle

# Tägliches inkrementelles Backup
0 2 * * * /usr/local/bin/wp-backup-incremental.sh

# Wöchentliches Vollbackup (Sonntag)
0 3 * * 0 /usr/local/bin/wp-backup-full.sh

# Monatliches Archiv (1. des Monats)
0 4 1 * * /usr/local/bin/wp-backup-archive.sh

Wiederherstellung

Datenbank wiederherstellen

# Mit WP-CLI
cd /var/www/wordpress
gunzip -c /backup/wordpress/backup-db.sql.gz | wp db import -

# Oder direkt mit MySQL
gunzip -c /backup/wordpress/backup-db.sql.gz | mysql -u user -p wordpress_db

Dateien wiederherstellen

# Dateien extrahieren
cd /var/www/wordpress
tar -xzvf /backup/wordpress/backup-files.tar.gz

# Berechtigungen korrigieren
chown -R www-data:www-data wp-content/
find wp-content/ -type d -exec chmod 755 {} \;
find wp-content/ -type f -exec chmod 644 {} \;

Komplette Wiederherstellung

#!/bin/bash
# wordpress-restore.sh

BACKUP_DIR="/backup/wordpress"
WP_PATH="/var/www/wordpress"

# Neuestes Backup finden
LATEST_DB=$(ls -t "$BACKUP_DIR"/*-db.sql.gz | head -1)
LATEST_FILES=$(ls -t "$BACKUP_DIR"/*-files.tar.gz | head -1)

echo "Stelle wieder her von:"
echo "DB: $LATEST_DB"
echo "Files: $LATEST_FILES"

read -p "Fortfahren? (j/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Jj]$ ]]; then
    exit 1
fi

cd "$WP_PATH"

# Maintenance-Mode
wp maintenance-mode activate

# Datenbank wiederherstellen
echo "Stelle Datenbank wieder her..."
gunzip -c "$LATEST_DB" | wp db import -

# Dateien wiederherstellen
echo "Stelle Dateien wieder her..."
tar -xzf "$LATEST_FILES"

# Berechtigungen
chown -R www-data:www-data wp-content/
find wp-content/ -type d -exec chmod 755 {} \;
find wp-content/ -type f -exec chmod 644 {} \;

# Cache leeren
wp cache flush

# Maintenance-Mode aus
wp maintenance-mode deactivate

echo "Wiederherstellung abgeschlossen!"

Remote-Backup

Backup auf externen Server

#!/bin/bash
# Nach lokalem Backup auf Remote kopieren

BACKUP_DIR="/backup/wordpress"
REMOTE_USER="backup"
REMOTE_HOST="backup.example.com"
REMOTE_DIR="/backups/wordpress"

# Mit rsync
rsync -avz --progress \
    "$BACKUP_DIR/" \
    "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"

Backup zu S3

# AWS CLI installieren
apt install awscli

# Konfigurieren
aws configure

# Upload-Skript
#!/bin/bash
BACKUP_FILE="$1"
BUCKET="mein-backup-bucket"
aws s3 cp "$BACKUP_FILE" "s3://$BUCKET/wordpress/"

Backup zu rclone (S3, Dropbox, etc.)

# rclone installieren
apt install rclone

# Konfigurieren
rclone config

# Backup hochladen
rclone sync /backup/wordpress remote:wordpress-backups

WP-CLI Backup-Befehle

Nützliche WP-CLI Befehle

# Nur bestimmte Tabellen sichern
wp db export --tables=wp_posts,wp_postmeta backup-posts.sql

# Datenbank-Informationen
wp db size

# Tabellen auflisten
wp db tables

# Suchmaschinen während Backup blockieren
wp option update blog_public 0

# Nach Restore wieder aktivieren
wp option update blog_public 1

Plugin-Liste sichern

# Installierte Plugins auflisten
wp plugin list --format=csv > plugins.csv

# Plugins bei Restore installieren
while IFS=, read -r name status version; do
    wp plugin install "$name" --activate
done < plugins.csv

Backup-Validierung

Backup-Integrität prüfen

#!/bin/bash
# verify-backup.sh

BACKUP_DIR="/backup/wordpress"

# Checksummen prüfen
for sha_file in "$BACKUP_DIR"/*.sha256; do
    if [ -f "$sha_file" ]; then
        cd "$(dirname "$sha_file")"
        if sha256sum -c "$sha_file" --quiet; then
            echo "✓ $(basename "$sha_file"): OK"
        else
            echo "✗ $(basename "$sha_file"): FEHLER!"
        fi
    fi
done

# Archive testen
for archive in "$BACKUP_DIR"/*.tar.gz; do
    if tar -tzf "$archive" > /dev/null 2>&1; then
        echo "✓ $(basename "$archive"): OK"
    else
        echo "✗ $(basename "$archive"): Beschädigt!"
    fi
done

# SQL-Dumps testen
for sql in "$BACKUP_DIR"/*.sql.gz; do
    if gunzip -t "$sql" 2>/dev/null; then
        echo "✓ $(basename "$sql"): OK"
    else
        echo "✗ $(basename "$sql"): Beschädigt!"
    fi
done

Zusammenfassung

| Methode | Vorteile | Nachteile | |---------|----------|-----------| | WP-CLI | Einfach, WordPress-nativ | Benötigt CLI-Zugang | | mysqldump | Schnell, zuverlässig | Manueller | | Plugins | Benutzerfreundlich | Oft kostenpflichtig | | Skripte | Flexibel, automatisierbar | Mehr Aufwand |

Fazit

Automatisierte WordPress-Backups mit WP-CLI und Shell-Skripten sind zuverlässiger als Plugin-Lösungen und bieten volle Kontrolle. Sichern Sie täglich Datenbank und Dateien, speichern Sie Backups extern und testen Sie regelmäßig die Wiederherstellung. Ein gutes Backup-System macht den Unterschied zwischen einem verlorenen Tag und einer verlorenen Website.