Sichere WordPress-Updates mit einem Staging-System

WordPress-Update im Livebetrieb: Wie aus dem Segen ein Fluch werden kann

Zugegeben, es ist schon sehr komfortabel, WordPress und seine Plugins upzudaten. Man wird informiert, welche Updates verfügbar sind, ein Klick und schon ist man wieder auf dem neuesten Stand. Probleme gibt es dabei selten.

Was aber, wenn doch? Gerade wenn viele Plugins im Einsatz sind oder Plugins, die etwas in die Jahre gekommen sind, ist die Gefahr von Inkompatibilitäten nach einem Update gegeben. Dann ist das Layout zerschossen, es erscheinen Fehlermeldungen auf der Seite oder die Seite ist gar komplett leer. Im schlimmsten Fall kann es zu Datenverlusten kommen.

Je nach Webseite kann das einen wirtschaftlichen Schaden mit sich bringen oder zumindest das Vertrauen der Besucher schmälern. Aber das muss auch alles nicht sein...

So könnte eine Webseite nach einem Update aussehen. Peinlich und geschäftsschädigend!

Die Lösung: Ein Staging-System

Was bei Enterprise-Software üblich ist, wird in der WordPress-Szene selten genutzt: die Einrichtung eines Staging- oder Testsystems, welches dazu dient, Änderungen am Live-System zuvor zu testen. Im Falle der Update-Funktion wäre es dann so, dass diese zunächst auf dem Staging-System durchgeführt wird. Durch manuelles Testen lässt sich anschließend sicherstellen, dass alles noch am rechten Fleck ist und keine Fehler auftreten.

Mein typisches Setup sieht ein Staging-System vor, welches entkoppelt vom Live-System ist. Es gibt also:

  • 2 URLs, z.B. www.example.com und staging.example.com
  • 2 Orte auf dem Webspace, z.B. /user/12345/production und /user/12345/staging
  • 2 Datenbanken

Der Content der Seiten wird nicht synchronisiert. Ändere ich auf einem der Systeme Inhalte, sind diese auf dem anderen System unverändert. Das ist meiner Meinung nach aber kein Nachteil, im Gegenteil, es erlaubt, auf einem Staging-System neue Inhalte zu entwickeln oder Plugins auszuprobieren, ohne dass das Live-System davon betroffen ist.

Kopplung der Systeme über Git und Revisr

Ich bin großer Fan von Git und dem Revisr-Plugin. Mehr dazu in meinem Artikel: Update zu Git vs. WordPress: Deployment mit Revisr.

Bezogen auf das Staging- und Live-System bedeutet das, dass Änderungen am Code des Staging-Systems in ein Git-Repository gepusht* werden. Dabei reicht mir üblicherweise ein Branch (master). Auf dem Live-System werden diese Änderungen dann gepullt*. Auf dem Live-System ist die Update-Funktion von WordPress dadurch nicht mehr notwendig.

*da commit, push und pull feststehende Begriff in der Git-Welt sind, verwende ich hier die denglische Form.

Schritt-für-Schritt-Anleitung: Einrichten eines Staging-Systems

Das folgende Vorgehen zur Einrichtung eines Staging-Systems hat sich für mich als Best-Practice herausgestellt.

Einrichtung einer Subdomain und einer frischen Datenbank

Diese Schritte sind im Backend des Webhosters durchzuführen. Die eingerichtete Subdomain zeigt auf einen eigenen Ordner im Webspace. Am besten heißt dieser staging oder test und liegt neben dem live oder production Ordner.

Annahme für diese Anleitung:

  • URL: staging.example.com
  • Webspace-Ordner /user/12345/staging

Einrichtung eines devtools-Ordners

In einem Ordner devtools lege ich webbasierte Werkzeuge ab, die bei der Einrichtung aber auch für den Betrieb hilfreich sind. Diesen schütze ich mit HTTP-Authentifizierung per .htaccess und .htpasswd Datei.

PHP Shell

PHP Shell bietet eine webbasierte Kommandozeile. Das ist ein mächtiges Tool, welches mit Vorsicht zu bedienen ist. Es kann als Ersatz für SSH dienen. Als Alternative zu SSH hat es den Vorteil, dass der Zugriff auf den Server mit denselben Benutzerdaten und Benutzerrechten geschieht wie der Aufruf der WordPress-Seite bzw. des WordPress-Backends.

Ich kopiere in die PHP Shell in den devtools-Ordner und kann diese über http://staging.example.com/devtools/phpshell-2.4/phpshell.php aufrufen. Damit ich Zugriff habe, muss ich in der Datei config.php meine Benutzerdaten einsetzen.

PHP Shell in Aktion. Für das Eingeben der Befehle ist ein bisschen Know-How erforderlich.

Git-Repository klonen

Annahme: Der Code der Seite besteht bereits in einem Git-Repository.

In der Kommandozeile der PHP Shell klone ich das Repository. Das Klonen in einen nichtleeren Ordner ist nicht möglich. Der Zielordner /user/12345/staging ist nicht leer, da hier die devtools liegen. Daher klone ich einen beliebigen Ordner und verschiebe per FTP den Inhalt samt .git-Verzeichnis an sein Ziel.

Wichtig: Bei günstigen Hostern ist häufig der authorisierte Zugriff auf das Git-Repository nur möglich mit dem Passwort in der Repository-URL, z.B. im Fall von Bitbucket https://<user>:<password>@bitbucket.org/<owner>/<repo>.git. Das Passwort steht dann leider im Klartext in der Datei /user/12345/staging/.git/config. Um den Aufruf der Datei von außen (http://staging.example.com/.git/config) zu schützen, hilft folgende Zeile in /user/12345/staging/.htaccess:

RedirectMatch 404 /\.

Datenbank und Dateien kopieren

Damit das Staging-System denselben Inhalt hat wie das Produktionssystem, muss ich Dateien und Datenbankdaten kopieren. Das mache ich zunächst nur einmal. Sollten sich die Inhalte der Systeme mit der Zeit stark auseinander entwickeln und man möchte, dass das Staging-System wieder wie das Live-Sysystem aussieht, lassen sich diese Schritte jederzeit wiederholen.

Die Datenbank lässt sich am besten mit phpMyAdmin kopieren. Dort die Quelldatenbank auswählen, Dump-Datei exportieren, Zieldatenbank auswählen und Dump-Datei importieren.

Ich halte den WordPress uploads-Ordner nicht im Git-Repository, da der Inhalt mit der Datenbank verbunden ist und diese unabhängig vom Code ist. Der uploads-Ordner des neuen Staging-Systems ist zunächst leer. Mit der PHP Shell lässt sich der upload-Ordner der Live-Seite mit einem Befehl in das Staging-System kopieren, sofern beide auf demselben Dateisystem liegen. Beispiel:

cp -r /user/12345/production/wp-content/uploads/ /user/12345/staging/wp-content/uploads/

wp-config.php erstellen

Ob ich die wp-config.php von der produktiven Webseite kopiere und anpasse oder mir die Datei von WordPress durch Aufruf der Staging-URL erzeugen lasse, ist gleich.

Der Aufruf der Staging-URL startet die WordPress-Installation, sofern die Datei wp-config.php noch nicht besteht.

URLs in Datenbank ersetzen

Ich habe nun eine 1:1 Kopie der Datenbank. Leider speichert WordPress die URL einzelner Posts in der Datenbank. Dort steht nun noch immer http://www.example.com obwohl ich das Staging-System unter http://staging.example.com betreiben möchte.

Dazu erweitere ich meine Werkzeugkiste und lade per FTP die Webanwendung Search-Replace-DB in das devtools-Verzeichnis. Über die Oberfläche kann ich nun in der gesamten Datenbank jegliche Vorkommnisse bestimmter Text-Strings ersetzen, z.B. URLs oder E-Mail-Adressen.

Seite für Suchmaschinen sperren

Die Bots der Suchmaschinen haben auf dem Staging-System nichts verloren. Würden sie den Inhalt indizieren, hätte das die Folge, dass dieser als Duplicate Content gewertet würde, und die produktive Seite im Suchmaschinenranking an Wert verliert.

Fertig! Das Staging-System lässt sich nun im Browser aufrufen. Es sollte exakt so aussehen wie das Live-System.

Der neue Update-Prozess: erst Staging-, dann Live-System

Mit einem laufenden Staging-System kann ich mit gutem Gewissen die WordPress-Update-Funktion nutzen. Sollte hier was schiefgehen, habe ich zwar immer noch ein Problem, denn das Update lässt sich dann nicht anwenden und mein Live-System wäre auf die installierte Version festgelegt, aber wenigstens läuft meine Live-Webseite ohne Probleme weiter. Das Update-Problem kann ich in aller Ruhe lösen.

Schon wieder 9 Updates verfügbar... Dann mal los!

Voraussetzung: Regelmäßige Backups

Bevor das Live-System verändert wird, sollte ein Backup erstellt werden. Entweder kurz vorher oder in einem nächtlichen Backup-Prozess. Ich setze dafür das Plugin BackWPUp ein. Es spricht nichts dagegen, auch Backups des Staging-Systems zu erstellen, sofern genug Speicherplatz vorhanden ist. Ich konfiguriere BackWPUp so, dass

  • nächtlich um drei ein Backup erstellt wird, ausgelöst durch WordPress cron
  • die Datenbank vollständig gesichert wird
  • nur der uploads-Ordner gesichert wird, da der Rest in einem Git-Repository liegt und damit bereits gesichert ist
  • das Backup in einem Ordner im Dateisystem abgelegt wird

BackWPUp, mein nächtlicher Helfer

Falls eine Webseite häufig geändert wird, empfehle ich vor einem Update zusätzlich ein manuelles Backup.

Nach dem Update: Testen!!

Nun gilt es, das System gründlich zu testen. Tut man das nicht und ein Fehler gelangt so in das Live-System, ist durch den gesamten hier beschriebenen Prozess nichts gewonnen!

Der Testumfang richtet sich nach der Komplexität der Installation. Wird ein Premium-Theme verwendet? Welche Plugins sind installiert? Welche Plugins wurden upgedatet?

Committen und Pushen auf dem Staging-System mit Revisr

Wie bereits beschrieben, setze ich auf meinen WordPress-Installationen das Revisr-Plugin ein, wodurch WordPress mit einem Git-Repository verbunden ist. Nach dem Update meldet Revisr uns in der Toolbar, dass sich Dateien geändert haben.

Durch Klicken auf diese Meldung gelange ich in einen Commit-Dialog. Hier werden mir alle geänderten Dateien angezeigt. Ich vergebe eine sprechende Bezeichnung für meine Änderungen, hier: Update WordPress to 4.7.2. Damit die Änderungen in mein Remote-Git-Repository (z.B. auf Bitbucket oder Github) gelangen, wähle ich rechts die Checkbox Push changes? aus. Tue ich das nicht, kann ich das Pushen nachträglich durchführen. Vergesse ich das Pushen, kann es später zu Konflikten führen, die ohne Fachkenntnisse schwer aufzulösen sind.

Pullen der Änderungen auf dem Live-System mit Revisr

Auf dem dem Live-System kann ich nun die Änderungen pullen. Auf dem Revisr Dashboard werden mir verfügbare Git-Revisionen als Zahl in Klammern auf dem Pull Changes Button dargestellt:

Durch Klick auf den Button erscheint ein Dialog.

Durch Klick auf Pull Changes werden die Änderungen geladen. Auf dem Dashboard erscheint eine Meldung, dass erfolgreich gepullt wurde:

Nach einem Refresh der Seite verschwinden schließlich auch Meldungen zu verfügbaren Updates. Diese wurden durch das Pullen des Codes durchgeführt.

Aktivierung von Lizenzen

Kommerzielle Plugins erwarten häufig eine Aktivierung, damit automatische Updates möglich sind. Hier macht es unter Umständen Sinn, nicht das Live- sondern das Staging-System zu aktivieren. Das hängt allerdings vom Plugin, der Lizenz und der Aktivierungslogik ab und muss von Fall zu Fall entschieden werden.

Installation von Plugins

Plugins sollten zunächst auf dem Staging-System installiert werden. Dort können sie getestet werden. Funktioniert alles wie erwartet, ist das Vorgehen exakt wie beim Update. Revisr sollte darüber informieren, dass neue Dateien erkannt wurden:

Das Committen geschieht dann wie oben beschrieben: Commit-Message eintragen, Checkbox Push Changes? anwählen und Commit Changes klicken.

Auf das Live-System wechseln, pullen und das Plugin ist auch dort verfügbar.

 

bjoerne_com_bjoern_weinbrenner_softwareentwickler_icon_leistungen_02

Lust auf mehr? Als Experte für WordPress und individuelle WordPress-Entwicklung kann ich Sie in Ihren Projekten unterstützen. Melden Sie sich gerne bei mir.

2017-02-09T14:26:37+00:00 30.01.2017|Tags: , , , , |3 Comments

3 Kommentare

  1. Martin 30. Januar 2017 um 20:55 Uhr- Antworten

    Hallo Björn, Danke für deinen informativen Artikel und, dass du deine Erkenntnisse mit uns teilst. PHP-Shell werde ich mir auf jeden Fall anschauen und nach deiner Anleitung hier probieren. Auch das Tool "Search-Replace-DB" finde ich klasse und kannte ich so noch nicht. Und das Plugin Revisr kenne ich ja nur durch deine Empfehlung. Es erleichtert mir ungemein die Arbeit und kann ich auch wärmstens weiterempfehlen. Mit der PHP-Shell wird alles sicher noch schneller gehen. Top.

    Grüße
    Martin

  2. Renaud 26. April 2017 um 9:19 Uhr- Antworten

    Hallo Björn, wir arbeiten uns durch dein Totorial durch. Sehr klar, super! stolpern aber gerade bei "Git-Repsitory klonen"...

    "In der Kommandozeile der PHP Shell klone ich das Repository. Das Klonen in einen nichtleeren Ordner ist nicht möglich. Der Zielordner /user/12345/staging ist nicht leer, da hier die devtools liegen. Daher klone ich einen beliebigen Ordner und verschiebe per FTP den Inhalt samt .git-Verzeichnis an sein Ziel."

    Heißt das, $ git clone verwenden? Wenn du sagst: "einen beliegigen Ordner klonen", bedeutet das in dem Fall "kopieren" oder meinst du "in einen beliebigen Ordner"? Und bei "an sein Ziel" meinst du da /user/12345/staging?

    Lieben Dank
    Renaud (La Berlinoise)

    • bjoerne 18. Mai 2017 um 22:58 Uhr- Antworten

      Hallo Renaud!
      Sorry für die späte Antwort! Ein beliebiger Ordner kann ein temp-Verzeichnis sein. Das Verzeichnis erstellen, in das Verzeichnis wechseln und dort git clone ausführen. Anschließend in den Ordner verschieben, auf den die Domain oder Subdomain zeigt.
      Viele Grüße
      Björn

Hinterlassen Sie einen Kommentar