WordPress-Staging-Umgebung per WP-CLI einrichten: Änderungen sicher testen, bevor sie live gehen
Private Kopie der WordPress-Website auf einer Subdomain anlegen: Dateien und Datenbank kopieren, Adressen mit wp search-replace umschreiben, Kopie per Passwort, noindex und Mail-Sperre abschotten. Im Labor mit WordPress 7.1.2 getestet.
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

Ein Plugin-Update, ein neues Theme oder eine geänderte PHP-Version kann eine WordPress-Website lahmlegen, und zwar genau dann, wenn Kunden sie aufrufen. Eine Staging-Umgebung ist eine private Kopie Ihrer Website, auf der Sie solche Änderungen zuerst ausprobieren. Diese Anleitung zeigt den Weg per SSH und WP-CLI auf dem eigenen Server oder Webhosting mit Shell-Zugang: Dateien und Datenbank kopieren, Adressen sauber umschreiben, die Kopie für Suchmaschinen und Besucher sperren und E-Mails abschalten. Alle Befehle stammen aus dem WP-CLI-Handbuch und wurden in einem Testlabor mit WordPress 7.1.2 ausgeführt.
Voraussetzungen
- WordPress: eine laufende Installation, getestet mit WordPress 7.1.2.
wp_get_environment_type()gibt es seit WordPress 5.5. - PHP: die Version, die Ihre Live-Seite nutzt. Staging und Live sollten dieselbe PHP-Version haben, sonst testen Sie etwas anderes, als live läuft. Im Labor lief PHP 8.4.
- Zugriff: SSH auf den Server oder das Webhosting, WP-CLI (getestet mit 2.12.0), Zugriff auf die Verwaltung Ihres Hosters, um eine Subdomain und eine zweite Datenbank anzulegen.
- Rechte: Administrator in WordPress und Schreibrechte im Webverzeichnis.
- Speicherplatz: mindestens so viel freier Platz, wie Ihre Installation samt Mediathek belegt, dazu Platz für einen Datenbankexport.
- Backup: eine aktuelle, geprüfte Sicherung der Live-Seite. Sie arbeiten zwar auf einer Kopie, aber ein Tippfehler im Datenbanknamen trifft sonst die Live-Datenbank.
Bietet Ihr Hoster eine Staging-Funktion an, nutzen Sie diese. Die folgenden Schritte zeigen auch, worauf Sie dort achten sollten.
Schritt 1: Subdomain, Verzeichnis und Datenbank vorbereiten
Die Kopie braucht eine eigene Adresse, ein eigenes Verzeichnis und eine eigene, leere Datenbank. Eine Subdomain wie staging.example.de verhält sich bei Cookies und Pfaden wie die Live-Seite. Legen Sie Subdomain und Datenbank in der Verwaltung Ihres Hosters an und notieren Sie Datenbankname, Benutzer, Passwort und Host.
Verwenden Sie für die Kopie einen eigenen Datenbankbenutzer, der nur auf die Staging-Datenbank zugreifen darf. So kann ein falscher Befehl auf der Kopie die Live-Daten technisch nicht erreichen.
In den Beispielen liegt die Live-Seite unter /var/www/live, die Kopie unter /var/www/staging. Passen Sie die Pfade an Ihren Server an. Erstellen Sie zuerst eine Sicherung der Live-Datenbank:
cd /var/www/live
wp db export ~/live-vor-staging.sql
Verifizieren: Die Subdomain liefert eine Seite des Hosters oder einen leeren Ordner aus, und WP-CLI meldet Success: Exported to '/home/.../live-vor-staging.sql'.
Schritt 2: WordPress-Dateien kopieren und Datenbankzugang anpassen
Kopieren Sie den kompletten Inhalt des Live-Verzeichnisses, also WordPress-Kern, wp-content mit Themes, Plugins und Uploads sowie wp-config.php und .htaccess. Ein Archiv erhält Rechte und Zeitstempel:
cd /var/www/live
tar czf ~/live-dateien.tgz .
mkdir -p /var/www/staging
tar xzf ~/live-dateien.tgz -C /var/www/staging
Die kopierte wp-config.php zeigt noch auf die Live-Datenbank. Das ändern Sie sofort, bevor Sie irgendeinen weiteren WP-CLI-Befehl im Staging-Verzeichnis ausführen:
cd /var/www/staging
wp config set DB_NAME staging_db
wp config set DB_USER staging_user
wp config set DB_PASSWORD 'IHR-STAGING-PASSWORT'
wp config get DB_NAME
Das Tabellenpräfix ($table_prefix) bleibt unverändert, denn es muss zu den Tabellen passen, die Sie im nächsten Schritt importieren. Setzen Sie das Passwort in einfachen Anführungszeichen, damit die Shell Sonderzeichen wie $ nicht auswertet. Legen Sie das Archiv nie im Webverzeichnis ab, es enthält Zugangsdaten.
Verifizieren: wp config get DB_NAME im Verzeichnis /var/www/staging gibt den Namen der Staging-Datenbank aus, nicht den der Live-Datenbank.
Schritt 3: Datenbank in die Kopie importieren
Importieren Sie jetzt den Export aus Schritt 1 in die leere Staging-Datenbank. WP-CLI nutzt dafür die Zugangsdaten aus der wp-config.php des aktuellen Verzeichnisses, deshalb war die Prüfung in Schritt 2 so wichtig.
cd /var/www/staging
wp db import ~/live-vor-staging.sql
wp option get siteurl
Die letzte Zeile gibt noch die Live-Adresse aus, etwa https://www.example.de. Das ist erwartet, die Adresse steht in der importierten Datenbank. Rufen Sie die Kopie noch nicht im Browser auf, WordPress leitet sonst auf die Live-Seite weiter. Im Labor antwortete die Kopie in diesem Zustand mit HTTP/1.1 301 Moved Permanently und einem Location-Header auf die Live-Adresse.
Verifizieren: WP-CLI meldet Success: Imported from '...', und wp post list --fields=ID,post_title zeigt dieselben Beiträge wie live.
Schritt 4: Adressen mit wp search-replace umschreiben
Die Live-Adresse steckt nicht nur in den Optionen home und siteurl, sondern auch in Beitragsinhalten, Menüs, Widgets und Plugin-Einstellungen. Viele dieser Werte speichert WordPress als serialisierte PHP-Daten, in denen die Länge jeder Zeichenkette mitgespeichert ist. Ein einfaches REPLACE per SQL verändert die Länge, ohne die Längenangabe anzupassen, und die Daten werden unlesbar. wp search-replace behandelt serialisierte Daten korrekt.
Lassen Sie die Spalte guid aus. Die WordPress-Dokumentation zum Umzug einer Website betont, dass dieser Wert eine dauerhafte Kennung für Feeds ist und nie verändert werden soll. Führen Sie zuerst einen Probelauf aus:
cd /var/www/staging
wp search-replace 'https://www.example.de' 'https://staging.example.de' --skip-columns=guid --dry-run --report-changed-only
Die Ausgabe listet je Tabelle und Spalte, wie viele Ersetzungen anstehen. Sieht die Liste plausibel aus, führen Sie denselben Befehl ohne --dry-run aus. Im Labor meldete der echte Lauf:
Table Column Replacements Type
wp_options option_value 2 PHP
wp_posts post_content 3 SQL
wp_users user_url 1 SQL
Success: Made 6 replacements.
Die Zeile mit dem Typ PHP zeigt, dass WP-CLI hier serialisierte Daten gefunden und sie mit PHP statt SQL bearbeitet hat. Ohne --skip-columns=guid meldete der Probelauf im Labor 10 statt 6 Ersetzungen, die zusätzlichen vier betrafen die Spalte guid. Prüfen Sie außerdem, ob Ihre Seite die Adresse auch ohne www oder mit http:// gespeichert hat, und wiederholen Sie den Probelauf für diese Schreibweisen.
Verifizieren: wp option get home und wp option get siteurl geben die Staging-Adresse aus, und ein zweiter Probelauf mit der alten Adresse meldet Success: 0 replacements to be made.
Schritt 5: Die Kopie abschotten
Eine offene Kopie wird indexiert, von Besuchern gefunden und verschickt E-Mails an echte Kunden. Schließen Sie alle drei Wege vor dem ersten Aufruf im Browser.
Passwortschutz: Der zuverlässigste Schutz ist eine HTTP-Authentifizierung vor der ganzen Seite. Auf Apache legen Sie eine Passwortdatei außerhalb des Webverzeichnisses an und setzen vier Zeilen an den Anfang der .htaccess der Kopie. Auf nginx erfüllen auth_basic und auth_basic_user_file im Server-Block denselben Zweck.
htpasswd -c /var/www/.htpasswd-staging pruefer
AuthType Basic
AuthName "Staging"
AuthUserFile /var/www/.htpasswd-staging
Require valid-user
Umgebungstyp: WordPress kennt die Werte local, development, staging und production. Ohne Angabe gilt production. Plugins und Themes fragen den Wert über wp_get_environment_type() ab und können sich auf einer Kopie zurückhalten. Zusätzlich setzen Sie die Sichtbarkeit für Suchmaschinen auf „aus“ und schalten WP-Cron ab, damit geplante Aufgaben wie Newsletter oder Backup-Uploads der Kopie nicht losgehen:
wp config set WP_ENVIRONMENT_TYPE staging --type=constant
wp config set DISABLE_WP_CRON true --raw --type=constant
wp option update blog_public 0
Die Option blog_public entspricht im Backend dem Kästchen „Suchmaschinen davon abraten, diese Website zu indexieren“ unter Einstellungen > Lesen > Sichtbarkeit für Suchmaschinen. WordPress gibt dann noindex, nofollow aus. Das ist eine Bitte an Suchmaschinen, kein Zugriffsschutz, deshalb ersetzt sie den Passwortschutz nicht.
E-Mails unterdrücken: Kontaktformulare, Shop-Plugins und Benutzerbenachrichtigungen verschicken über wp_mail(). Der Filter pre_wp_mail bricht den Versand ab, wenn er einen anderen Wert als null zurückgibt. Legen Sie dafür ein Must-Use-Plugin an, das nur in der Staging-Umgebung greift:
<?php
// Datei: wp-content/mu-plugins/staging-no-mail.php
// Staging: keine E-Mails versenden
if ( wp_get_environment_type() === 'staging' ) {
add_filter( 'pre_wp_mail', '__return_false' );
}
Weil das Plugin den Umgebungstyp abfragt, richtet es keinen Schaden an, wenn es beim nächsten Abgleich versehentlich auf der Live-Seite landet. Plugins, die E-Mails an wp_mail() vorbei direkt über eine API versenden, erfasst der Filter nicht. Deaktivieren Sie solche Plugins auf der Kopie oder tragen Sie dort Test-Zugangsdaten ein.
Verifizieren: curl -I https://staging.example.de/ ohne Zugangsdaten liefert HTTP/1.1 401 Unauthorized. Mit Zugangsdaten liefert die Seite 200, der Quelltext enthält <meta name='robots' content='noindex, nofollow' />, und unter Werkzeuge > Website-Zustand > Information steht im Bereich WordPress der Umgebungstyp „staging“. wp eval 'var_dump( wp_mail( "test@example.test", "Test", "Text" ) );' gibt bool(false) aus.
Schritt 6: Änderungen testen und auf die Live-Seite übertragen
Jetzt arbeitet die Kopie. Spielen Sie dort das geplante Update ein, wechseln Sie die PHP-Version der Subdomain oder testen Sie das neue Plugin. Prüfen Sie danach die Seiten, die für Ihr Geschäft zählen: Startseite, Kontaktformular, Warenkorb und Kasse, Login-Bereich. Aktivieren Sie auf der Kopie bei Bedarf das Debug-Log, wie in der Anleitung WordPress Debug-Modus aktivieren beschrieben, und lesen Sie es nach jedem Test.
Der heikle Teil ist der Rückweg. Kopieren Sie die Staging-Datenbank nicht einfach auf die Live-Seite zurück. Während Sie getestet haben, sind live neue Bestellungen, Kommentare, Formulareinträge und Benutzerkonten entstanden. Ein Zurückkopieren würde sie überschreiben. Der sichere Weg für kleine Unternehmen: Sie nutzen die Kopie als Probelauf und wiederholen die erfolgreich getesteten Schritte anschließend auf der Live-Seite, also dasselbe Update, dieselbe Plugin-Einstellung, dieselbe PHP-Version.
Halten Sie die Kopie aktuell, sonst testen Sie gegen einen veralteten Stand. Wiederholen Sie die Schritte 1 bis 5 vor jedem größeren Update. Damit werden Staging, Backup und Update zu einer festen Routine, die regelmäßig Zeit kostet. Wer diese Arbeit nicht selbst einplanen möchte, kann sie abgeben: Die WordPress-Wartung von wordpressupdate.de spielt Updates von WordPress, Plugins und Themes mit Kompatibilitätsprüfung ein, erstellt wöchentliche Backups auf externem Speicher und richtet die Firewall ein.
Verifizieren: Nach dem Update auf der Kopie zeigen wp core version und wp plugin list die neuen Versionen, alle geprüften Seiten laden ohne Fehler, und das Debug-Log enthält keine neuen Einträge vom Typ PHP Fatal error.
Typische Fehler
- Die Staging-Adresse leitet auf die Live-Seite weiter:
homeodersiteurlenthalten noch die alte Adresse. Im Labor antwortete die Kopie mit301 Moved Permanentlyauf die Live-Adresse. Wiederholen Sie Schritt 4 und prüfen Sie mitwp option get home. Error: Import file missing or not readable: Der Pfad zur SQL-Datei stimmt nicht, oder der ausführende Benutzer darf die Datei nicht lesen. Geben Sie den absoluten Pfad an und prüfen Sie ihn mitls -la.Error: Couldn't find any tables matching: Sie habenwp search-replaceeine Tabelle mit falschem Präfix übergeben. Lassen Sie die Tabellenangabe weg, dann bearbeitet WP-CLI alle Tabellen, die WordPress kennt.- Die Live-Seite zeigt plötzlich die Staging-Adresse:
wp search-replacelief mit den Zugangsdaten der Live-Datenbank, weil Schritt 2 übersprungen wurde. Spielen Sie das Backup aus Schritt 1 ein und prüfen Sie künftig vor jedem Befehlwp config get DB_NAME. - Error 500 nach dem Passwortschutz: Der Pfad in
AuthUserFilestimmt nicht. Das Apache-Fehlerprotokoll meldete im LaborAH01620: Could not open password file: /var/www/falsch/.htpasswd. Korrigieren Sie den Pfad und prüfen Sie, dass der Webserver die Datei lesen darf.
Häufige Fragen
Reicht die Einstellung „Suchmaschinen davon abraten“ als Schutz?
Nein. Sie setzt nur ein noindex, das seriöse Suchmaschinen beachten. Besucher, die die Adresse kennen, erreichen die Seite trotzdem. Erst der Passwortschutz aus Schritt 5 sperrt die Kopie wirklich.
Brauche ich ein Staging-Plugin?
Nicht zwingend. Staging-Plugins erledigen dieselben Schritte über eine Oberfläche. Mit WP-CLI sehen Sie genau, was passiert, und brauchen keine zusätzliche Software auf der Live-Seite.
Wie groß darf der Abstand zwischen Kopie und Live-Seite sein?
So klein wie möglich. Erstellen Sie die Kopie kurz vor dem geplanten Update neu. Eine Wochen alte Kopie sagt wenig über die Live-Seite aus.
Was ist mit DSGVO und Kundendaten auf der Kopie?
Die Kopie enthält dieselben personenbezogenen Daten wie die Live-Seite und braucht denselben Schutz. Löschen Sie nicht mehr benötigte Kopien samt Datenbank und Exportdateien.
Testumfang
Wir haben das Vorgehen mit WordPress 7.1.2 auf zwei getrennten Instanzen im Labor durchgespielt, vom Datenbankexport bis zum Ersetzen der Adressen mit wp search-replace. Der Passwortschutz auf Apache funktionierte, ohne Zugangsdaten blieb die Seite gesperrt. Nicht geprüft haben wir nginx, die Oberflächen der Hoster und Multisite, testen Sie in diesen Fällen daher zuerst auf einer Kopie.
Fazit
Eine Staging-Umgebung kostet beim ersten Mal etwa eine halbe Stunde und danach wenige Minuten pro Aktualisierung. Entscheidend sind drei Punkte: eine eigene Datenbank mit eigenem Benutzer, das Umschreiben der Adressen mit wp search-replace statt SQL und eine abgeschottete Kopie ohne E-Mail-Versand. Getestete Änderungen übertragen Sie gezielt, nie durch Zurückkopieren der Datenbank. Wenn Sie Updates und Backups lieber in feste Hände geben möchten, übernimmt das die WordPress-Wartung von Marcel Schönfelder.
Weiterführende Anleitungen und Quellen
- WordPress Debug-Modus aktivieren: Error-Logs analysieren und Fehler selbst beheben
- WordPress Cron Job einrichten: WP-Cron durch echten System-Cron ersetzen
- WordPress auf dem Synology NAS installieren: eigene Website oder Staging-Umgebung
- Backup-Restore-Test als feste Routine etablieren
- WordPress Developer Reference: wp_get_environment_type()
- WP-CLI-Handbuch: wp search-replace
- WordPress Advanced Administration: Moving WordPress (GUID-Hinweis)
- WordPress Developer Reference: Filter pre_wp_mail


