Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung WordPress 30.09.2026 · 11 min Lesezeit

WordPress-Wartung mit WP-CLI-Skripten automatisieren: Sicherung, Updates und Prüfung per Cronjob

Ein Shell-Skript mit WP-CLI sichert vor jedem Lauf die Datenbank, spielt nur Wartungs- und Patch-Versionen ein, prüft Dateien gegen Prüfsummen, fragt die Startseite ab und läuft per Cronjob mit Protokoll.

Mit KI erstellt – redaktionelle Prüfung ausstehend

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Mehr dazu

Grafik mit der Überschrift WordPress-Wartung mit WP-CLI und einem stilisierten WordPress-Adminbereich mit Terminalfenster

Wer WordPress über SSH pflegt, tippt jede Woche dieselben Befehle: Sicherung ziehen, Updates einspielen, prüfen, ob die Website noch läuft. Genau diese Routine lässt sich in ein Shell-Skript gießen, das per Cronjob nachts arbeitet und ein Protokoll hinterlässt. Diese Anleitung baut ein solches Skript mit WP-CLI auf: erst die Sicherung, dann nur kleine Updates, danach eine Prüfung der Dateien und ein Rückgabewert, der Fehler meldet. Große Versionssprünge bleiben bewusst Handarbeit, denn die brauchen einen Menschen, der danach die Website ansieht.

Voraussetzungen

  • Server: Linux-Server oder VPS mit SSH-Zugang und Root- bzw. sudo-Rechten. Für Wartungsskripte genügen 1 CPU-Kern und 1 GB RAM zusätzlich zur Website. Klassisches Webhosting ohne SSH und ohne eigene Cronjobs reicht für diese Anleitung nicht.
  • WordPress: eine aktuelle Version, im Test WordPress 7.1.2 mit PHP 8.4. Die Befehle funktionieren auch mit älteren 6.x-Versionen.
  • WP-CLI: installiert und als Befehl wp aufrufbar, im Test Version 2.12.0. wp db export braucht zusätzlich mariadb-dump oder mysqldump auf dem Server (Paket mariadb-client bzw. default-mysql-client).
  • Werkzeuge: bash, flock (Paket util-linux), curl, gzip und ein Cron-Dienst.
  • Rolle: Sie brauchen Zugriff auf den Linux-Benutzer, dem die WordPress-Dateien gehören (unter Debian und Ubuntu meist www-data). Ein Administrator-Konto im Backend brauchen Sie nur zur Kontrolle.
  • Backup: eine vollständige Sicherung von Dateien und Datenbank, die nicht auf demselben Server liegt. Das Skript ersetzt diese Sicherung nicht, es ergänzt sie um einen Datenbankstand direkt vor jedem Update.

Die Update-Befehle selbst erklärt WordPress-Updates per WP-CLI. Hier geht es darum, diese Befehle sicher zu verketten.

Schritt 1: Festlegen, was automatisch laufen darf

Ein Skript merkt nicht, ob nach einem Update das Kontaktformular noch funktioniert. Legen Sie deshalb vorher fest, was unbeaufsichtigt passieren darf. WP-CLI bietet dafür zwei Schalter. --minor beschränkt Updates laut Handbuch auf Nebenversionen, bei Plugins also etwa von 1.3 auf 1.4, aber nicht auf 2.0. --patch geht enger und erlaubt nur Patch-Versionen, etwa von 1.3 auf 1.3.3. Beim Core bedeutet wp core update --minor dagegen, dass nur Wartungs- und Sicherheitsversionen innerhalb der aktuellen Hauptversion eingespielt werden, also etwa 7.1.1 auf 7.1.2.

Den Unterschied zeigt eine Probe mit --dry-run, die nichts verändert:

sudo -u www-data wp plugin update --all --patch --dry-run
sudo -u www-data wp plugin update --all --minor --dry-run

Im Test stand das Plugin Classic Editor auf 1.6.3. Mit --patch bot WP-CLI Version 1.6.7 an, mit --minor dagegen 1.7.0. Achtung: Viele Plugins halten sich nicht an die Semantische Versionierung, eine Patch-Nummer garantiert also keine kleine Änderung. Plugins, bei denen jeder Fehler teuer wird (Shop, Zahlungsanbieter, Buchungssystem), nehmen Sie deshalb ganz aus und aktualisieren sie von Hand.

Verifizieren: Sie haben eine kurze Liste der Plugins, die ausgenommen werden, und die Probe mit --dry-run zeigt für die übrigen nur Versionen, die Sie automatisch zulassen möchten.

Schritt 2: Verzeichnisse und Benutzer vorbereiten

Das Skript läuft als Webserver-Benutzer, nicht als root. Dateien, die ein Update als root anlegt, kann WordPress später nicht mehr selbst ändern. Legen Sie ein Verzeichnis für die Sicherungen und eines für die Protokolle an und übergeben Sie beide an www-data:

sudo mkdir -p /var/backups/wordpress /var/log/wp-wartung
sudo chown www-data:www-data /var/backups/wordpress /var/log/wp-wartung
sudo chmod 750 /var/backups/wordpress /var/log/wp-wartung

Die Sicherungen enthalten Passwort-Hashes und Formulareingaben. Darum liegen sie außerhalb des Web-Verzeichnisses. Das Skript setzt zusätzlich umask 027, damit neue Dateien ebenfalls nur für Besitzer und Gruppe lesbar sind.

Verifizieren: ls -ld /var/backups/wordpress /var/log/wp-wartung zeigt drwxr-x--- und den Besitzer www-data, und sudo -u www-data wp --path=/var/www/html core version gibt die WordPress-Version aus.

Schritt 3: Das Wartungsskript anlegen

Legen Sie die Datei /usr/local/bin/wp-wartung.sh mit folgendem Inhalt an und passen Sie die Werte im oberen Block an Ihre Website an:

#!/usr/bin/env bash
# WordPress-Wartung: Sicherung, kleine Updates, Prüfungen. Aufruf als Webserver-Benutzer.
set -uo pipefail
umask 027

WP_PATH="${WP_PATH:-/var/www/html}"
BACKUP_DIR="/var/backups/wordpress"
LOG_DIR="/var/log/wp-wartung"
KEEP_DAYS=14
EXCLUDE_PLUGINS=""          # z. B. "woocommerce,shop-erweiterung"
SITE_URL="${SITE_URL:-https://www.ihre-domain.de/}"

export WP_CLI_CACHE_DIR="/tmp/wp-cli-cache"
WP="wp --path=$WP_PATH --no-color"
STAMP="$(date +%F_%H%M%S)"
LOG="$LOG_DIR/wartung_$STAMP.log"
FEHLER=0

mkdir -p "$BACKUP_DIR" "$LOG_DIR"
exec >>"$LOG" 2>&1

exec 9>"$LOG_DIR/.lock"
flock -n 9 || { echo "Wartung läuft bereits, Abbruch."; exit 2; }

schritt() { echo; echo "== $(date '+%F %T') $*"; }

schritt "Ausgangslage"
$WP core version
$WP core check-update
$WP plugin list --update=available --fields=name,version,update_version

schritt "Datenbank sichern"
if ! $WP db export "$BACKUP_DIR/db_$STAMP.sql"; then
  echo "FEHLER: Datenbanksicherung fehlgeschlagen, keine Updates."
  exit 1
fi
gzip -f "$BACKUP_DIR/db_$STAMP.sql"

schritt "Updates (nur Wartungs- und Patch-Versionen)"
$WP core update --minor || FEHLER=1
$WP core update-db || FEHLER=1
$WP plugin update --all --patch --exclude="$EXCLUDE_PLUGINS" || FEHLER=1
$WP theme update --all --patch || FEHLER=1
$WP language core update || FEHLER=1
$WP language plugin update --all || FEHLER=1
$WP language theme update --all || FEHLER=1

schritt "Prüfungen"
$WP core verify-checksums || FEHLER=1
$WP plugin verify-checksums --all || FEHLER=1
$WP transient delete --expired
CODE="$(curl -s -o /dev/null -w '%{http_code}' "$SITE_URL")"
echo "HTTP-Status Startseite: $CODE"
[ "$CODE" = "200" ] || FEHLER=1

schritt "Alte Sicherungen und Protokolle entfernen"
find "$BACKUP_DIR" -name 'db_*.sql.gz' -mtime +"$KEEP_DAYS" -print -delete
find "$LOG_DIR" -name 'wartung_*.log' -mtime +"$KEEP_DAYS" -print -delete

schritt "Ende, Fehlerstatus $FEHLER"
exit "$FEHLER"

Einige Stellen verdienen eine Erklärung. WP_CLI_CACHE_DIR lenkt den Download-Cache von WP-CLI in ein beschreibbares Verzeichnis. Ohne diese Zeile meldet WP-CLI beim Webserver-Benutzer oft Failed to create directory '/var/www/.wp-cli/cache/', weil dessen Home-Verzeichnis nicht beschreibbar ist. exec 9>… zusammen mit flock -n 9 sorgt dafür, dass nie zwei Läufe gleichzeitig Updates einspielen. Scheitert die Datenbanksicherung, endet das Skript, bevor es etwas verändert. Spätere Fehler setzen nur FEHLER=1, damit das Skript bis zum Ende prüft.

wp core update-db ist nach einem Core-Update wichtig, weil manche Versionen das Datenbankschema anpassen. Machen Sie das Skript danach ausführbar:

sudo chmod 755 /usr/local/bin/wp-wartung.sh

Verifizieren: bash -n /usr/local/bin/wp-wartung.sh läuft ohne Ausgabe durch.

Schritt 4: Das Skript von Hand testen

Starten Sie den ersten Lauf von Hand zu einer ruhigen Zeit:

sudo -u www-data /usr/local/bin/wp-wartung.sh; echo "Rückgabewert: $?"
sudo -u www-data tail -n 40 /var/log/wp-wartung/wartung_*.log

Im Protokoll steht jeder Abschnitt mit Zeitstempel. Im Test meldete der Lauf nacheinander die exportierte Datenbank, das eingespielte Patch-Update eines Plugins (classic-editor 1.6.3 1.6.7 Updated), erfolgreiche Prüfsummen und den HTTP-Status 200.

Prüfen Sie danach auch den Fehlerfall. Ein falscher Pfad genügt, um zu sehen, ob das Skript wirklich vor den Updates abbricht:

sudo -u www-data env WP_PATH=/tmp /usr/local/bin/wp-wartung.sh; echo "Rückgabewert: $?"

Im Test endete dieser Lauf mit Rückgabewert 1 und der Meldung Error: This does not seem to be a WordPress installation. direkt im Abschnitt „Datenbank sichern“. Updates wurden nicht versucht.

Verifizieren: Der normale Lauf endet mit „Ende, Fehlerstatus 0“ und Rückgabewert 0. In /var/backups/wordpress liegt eine Datei db_…sql.gz, und die Website zeigt im Browser keine Auffälligkeiten.

Schritt 5: Den Cronjob einrichten

Tragen Sie das Skript in die Crontab des Webserver-Benutzers ein. So läuft es ohne sudo mit den richtigen Rechten:

sudo crontab -u www-data -e
30 3 * * 2 SITE_URL=https://www.ihre-domain.de/ /usr/local/bin/wp-wartung.sh

Die Zeile startet die Wartung jeden Dienstag um 3:30 Uhr. Wählen Sie einen Werktag, an dem am Morgen jemand die Website ansieht, sonst bleibt ein Fehler übers Wochenende stehen. Cron kennt nur einen knappen Suchpfad. Liegt WP-CLI laut command -v wp nicht in /usr/local/bin oder /usr/bin, tragen Sie den vollen Pfad ins Skript ein.

Falls Sie WP-Cron bereits auf einen System-Cronjob umgestellt haben, wie in WordPress Cron Job einrichten beschrieben, bleibt dieser Eintrag davon unberührt.

Verifizieren: sudo crontab -u www-data -l zeigt die neue Zeile. Am Morgen nach dem ersten geplanten Lauf liegt ein neues Protokoll in /var/log/wp-wartung.

Schritt 6: Ergebnisse auswerten und Ausnahmen pflegen

Suchen Sie nach jedem Lauf im Protokoll nach Fehlern und Warnungen:

sudo -u www-data grep -H -E "Error|Warning|FEHLER|Fehlerstatus 1" /var/log/wp-wartung/wartung_*.log

Das Skript ändert bewusst nur kleine Versionen. Was offen bleibt, zeigt der Abschnitt „Ausgangslage“ im Protokoll, etwa ein Plugin von 1.6.7 auf 1.7.0 oder ein Theme mit neuer Nebenversion. Diese Updates spielen Sie weiterhin von Hand ein, nachdem Sie das Changelog gelesen haben. Wann welche Arbeit ansteht, fasst der Wartungsplan für WordPress zusammen.

Die Sicherungen auf dem Server helfen bei einem missglückten Update, nicht bei einem Serverausfall. Ein vollständiges Backup mit Dateien beschreibt WordPress-Backup auf dem Server per Cronjob und Shell-Skript.

Spätestens hier merken viele Betreiber, dass das Skript die Arbeit nicht beseitigt, sondern verschiebt: Protokolle lesen, größere Updates prüfen, Ausnahmen pflegen und Sicherungen auswärts lagern bleibt Woche für Woche Aufgabe eines Menschen. Wer das nicht selbst im Kalender halten möchte, kann es abgeben: Die WordPress-Wartung von wordpressupdate.de spielt Updates von WordPress, Plugins und Themes innerhalb von 48 Stunden mit Kompatibilitätsprüfung ein und sichert die Website wöchentlich auf externen Speicher mit vier Wochen Aufbewahrung.

Verifizieren: Die Suche im Protokoll findet keine Treffer, und im Backend unter „Dashboard“ › „Aktualisierungen“ stehen nur noch die Updates, die Sie bewusst von Hand einspielen wollen.

Typische Fehler

  • Error: YIKES! It looks like you're running this as root. Das Skript oder WP-CLI wurde als root gestartet. Starten Sie es mit sudo -u www-data oder aus der Crontab von www-data. --allow-root hinterlässt Dateien, die root gehören.
  • env: 'mysqldump': No such file or directory WP-CLI ruft für wp db export und wp db check externe Programme auf. Installieren Sie das Paket mariadb-client (oder default-mysql-client).
  • Failed to create directory '/var/www/.wp-cli/cache/': mkdir(): Permission denied. Das Home-Verzeichnis des Webserver-Benutzers ist nicht beschreibbar. Die Zeile export WP_CLI_CACHE_DIR=… im Skript behebt das.
  • „Wartung läuft bereits, Abbruch.“ mit Rückgabewert 2 Ein zweiter Lauf startete, während der erste noch arbeitete. Das ist gewollt. Kommt die Meldung bei jedem Lauf, hängt ein alter Prozess (pgrep -af wp-wartung).
  • „HTTP-Status Startseite: 301“ und Fehlerstatus 1 Die Adresse in SITE_URL leitet weiter, etwa von http auf https oder auf die Variante mit www. Tragen Sie die endgültige Adresse ein. curl folgt Weiterleitungen im Skript absichtlich nicht, damit eine falsche Weiterleitung auffällt.
  • Warning: File should not exist: … wp core verify-checksums hat im Core-Verzeichnis eine Datei gefunden, die nicht zu WordPress gehört. Das kann harmlos sein (im Test eine Datei des Docker-Images) oder auf eingeschleusten Code hindeuten. Wie Sie das einordnen, zeigt WordPress-Dateien mit Prüfsummen kontrollieren.
  • Warning: Could not retrieve the checksums for version … of plugin …, skipping. Kauf-Plugins und selbst geschriebene Plugins stehen nicht im Verzeichnis auf wordpress.org, deshalb gibt es für sie keine Prüfsummen. WP-CLI überspringt sie und meldet etwa Verified 3 of 4 plugins (1 skipped). Das ist kein Fehler, diese Plugins bleiben aber ungeprüft.

Häufige Fragen

Warum nicht einfach die automatischen Updates von WordPress nutzen?

Die eingebauten automatischen Updates sind für viele Websites eine gute Wahl. Das Skript ergänzt eine Datenbanksicherung direkt vor jedem Update, ein Protokoll und eine Prüfsummenkontrolle. Nutzen Sie nur einen der beiden Wege, damit klar ist, wer wann aktualisiert.

Kann ich auch Hauptversionen automatisch einspielen?

Technisch ja, ohne --minor und --patch. Davon ist abzuraten, weil Hauptversionen Funktionen ändern und niemand danach die Website kontrolliert. Spielen Sie solche Updates von Hand ein, idealerweise zuerst auf einer Testkopie.

Wie mache ich ein Update mit dem Skript rückgängig?

Die Datenbank stellen Sie mit gunzip -c db_DATUM.sql.gz | sudo -u www-data wp db import - wieder her. Ein Plugin setzen Sie mit wp plugin install NAME --version=ALTE_VERSION --force auf den vorherigen Stand zurück. Dateien des Themes oder hochgeladene Medien sichert das Skript nicht, dafür brauchen Sie Ihre vollständige Sicherung.

Testumfang

Wir haben das Skript auf einer Testinstallation mit WordPress 7.1.2 mehrfach laufen lassen. Es sicherte die Datenbank, spielte nur die Patch-Version ein und ließ das größere Update liegen. Ein echtes Core-Wartungsupdate, Multisite und Kauf-Plugins mit eigenem Update-Mechanismus haben wir nicht geprüft. Wenn Sie so etwas einsetzen, lassen Sie das Skript zuerst auf einer Kopie Ihrer Website laufen.

Fazit

Ein Wartungsskript mit WP-CLI nimmt Ihnen die stupiden Teile der WordPress-Pflege ab und macht sie nachvollziehbar: Jeder Lauf beginnt mit einer Sicherung, ändert nur kleine Versionen und endet mit einer Prüfung und einem Protokoll. Die Entscheidung über größere Updates und der Blick auf die Ergebnisse bleiben trotzdem bei Ihnen. Wer diese laufende Kontrolle lieber abgibt, findet bei der WordPress-Wartung von Marcel Schönfelder einen Ansprechpartner, der Updates und Backups übernimmt.

Weiterführende Anleitungen und Quellen

WordPressWP-CLIWartungCronjobShell-Skript