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.phpWichtigste 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 --infoWP-CLI für Webserver-User
# Als www-data ausführen
sudo -u www-data wp --info --path=/var/www/wordpressDatenbank 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).sqlDirekt 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.sqlOptimierte Optionen
# Mit erweiterten Optionen
mysqldump -u "$DB_USER" -p"$DB_PASS" \
--single-transaction \
--quick \
--lock-tables=false \
--routines \
--triggers \
"$DB_NAME" | gzip > backup.sql.gzDateien 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).phpMit 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 0Skript einrichten
# Ausführbar machen
chmod +x /usr/local/bin/wordpress-backup.sh
# Testen
/usr/local/bin/wordpress-backup.shAutomatisierung 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>&1Verschiedene 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.shWiederherstellung
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_dbDateien 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-backupsWP-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 1Plugin-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.csvBackup-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
doneZusammenfassung
| 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.