WordPress auf Webspace ohne PHP und MySQL

WordPress ist ein sehr leistungsfähiges CMS und Blog-System. Die Software ist in PHP geschrieben und benötigt eine MySQL-Datenbank zum Speichern der Artikel. Deswegen benötigt WordPress zwingend Webspace mit PHP-Unterstützung und MySQL-Datenbank. Wirklich?

Oft hat heute Webspace diese benötigte Ausstattung, aber nicht immer. Dieser Webspace, auf dem mein Blog liegt, kann nichts mit PHP anfangen und hat auch keine Datenbank

Für einen Webserver gibt es nichts Einfacheres,  als eine statische HTML-Seite auszuliefern. Bei WordPress muss der PHP-Code ausgeführt werden, der dann noch einige Datenbankabfragen startet. All das kostet Zeit. Die Antwortzeit eine Webseite ist inzwischen auch ein Ranking-Faktor bei Google…

WordPress ist (vollkommen zu Recht) ein sehr populäres System. Dadurch ist es natürlich auch ein beliebtes Angriffsziel. PHP hat immer mal die ein oder andere Sicherheitslücke. Auch Programmierfehler in WordPress selber oder den Themes können die Webseite verletzlich machen.

Zum Bearbeiten meldet man sich mit Benutzername und Passwort am Backend an. Ist die Verbindung nicht mit https abgesichert, dann lassen sich Benutzername und Passwort unterwegs abfangen und der Webspace damit kapern.

Statische HTML-Seiten minimieren alle Sicherheitsprobleme.

Wie kann man nun die Vorteile des Komforts von WordPress mit den Vorteilen statischer HTML-Seiten unter einen Hut bringen? Ich möchte hier einen möglichen Weg aufzeigen.

Die Idee

Ursprünglich wollte ich für diese Seite hier gar kein WordPress verwenden. Ich habe zunächst nach einem System gesucht, mit dem die Texte in einem einfachen Texteditor wie gedit geschrieben werden können, eventuell in Markdown. Aus den Textdateien sollten dann per Skipt alle HTML-Dateien sowie die anderen notwendigen Dateien erzeugt werden.

Ich wusste, dass es speziell für Podcaster so ein System gibt, Mikrowelle-OS. Das System ist in Python geschrieben. Mangels Python-Kenntnisse kam aber eine Anpassung für mich nicht in Frage. Also machte ich mich auf die Suche nach einem ähnlichen Systems, das für Blogs ausgelegt ist.

Da bin ich auf Letterpress gestoßen. Das ist war eigentlich genau das, wonach ich gesucht hatte. Der einzige Haken war, dass ich es auf meinem Computer nicht richtig zum Laufen gebracht habe. Für mich unverständliche Fehlermeldungen und fehlende Python-Kenntnisse standen dem im Weg. Die Informationen zu Letterpress im Web waren auch sehr begrenzt.

Also bin ich doch wieder bei WordPress gelandet. Ich dachte mir, dass es vielleicht ein Plugin gibt, das statische Seiten generiert. Really Static ist so eins. Auf meiner lokalen WordPress-Installation wollte es allerdings aus unerfindlichen Gründen nicht richtig laufen. Bevor ich mich auf die lange Fehlersuche machte, überlegte ich, ob es eigentlich nicht viel einfacher ging. Ich benutze einen Computer mit Linux und dieses Betriebssystem verfügt über eine Kommandozeile mit sehr vielen leistungsfähigen Befehlen. Einer dieser Befehle ist wget. Ich wusste, dass man mit diesem Tool ganze Seiten crawlen und diese lokal speichern kann. Das war mein Ausgangspunkt.

Ich überlegte mir diesen groben Ablauf:

  1. Schreiben der Artikel in meiner lokalen WordPress-Installation.
  2. Crawlen meiner lokalen Webseite mit wget und Abspeichern als statische HTML-Seiten.
  3. Notwendige Korrekturen in den HTML-Dateien durchführen.
  4. Upload per ftp auf meinen Webspace.

Auf das automatisierte Hochladen verzichte ich vorerst. Erst wenn ich mir sicher bin, dass alles fehlerfrei läuft, werde ich auch das mit in das Skript aufnehmen.

Die Umsetzung

Lokale WordPress-Installation

Zunächst muss eine lokale WordPress-Installation her. Dafür sind folgende Voraussetzungen nötig:

  • Webserver Apache2
  • Datenbankserver MySQL
  • PHP5

Auf diese Voraussetzungen möchte ich gar nicht weiter eingehen. Es gibt dafür genügend gute Anleitungen im Web, z. B. im Ubuntu-Wiki:

Dann muss noch WordPress installiert werden. Auch dafür gibt es genügend gute Anleitungen, wie dieses hier, so dass ich das hier nicht weiter beschreiben möchte.

Ist das alles erfolgreich absolviert, dann ist das WordPress-Backend im Browser erreichbar, bei mir unter http://localhost/blog/wp-admin. Hier können nun wie gewohnt die Artikel verfasst werden.

Umwandeln in statische Seiten

Als Vorbereitung wird zunächst ein Arbeitsordner angelegt, z. B. /home/MeinName/Blog/.

In diesem Ordner wird ein Shellskipt angelegt. Es wird eine Textdatei erzeugt. Ich habe sie bei mir wp2html.sh genannt. Diese Datei muss aufführbar gemacht werden:

Datei ausführbar machen

Mit #!/bin/bash in der ersten Zeile der Datei teilt man dem Betriebssystem mit, dass es sich hier um ein Shellskript handelt.

Mit dem folgenden Befehl werden die dynamischen Seiten als statische HTML-Seiten abgespeichert:
wget -r -k -E -l 8 http://localhost/blog

Die Option -r bewirkt, dass wget jedem Link nachgeht und das verlinkte Dokument ebenfalls abspeichert.

Wichtig ist die Optione -k. Damit werden in den lokal gespeicherten Dokumenten alle externen Links zu internen konvertiert. Aus http://localhost/blog/index.html wird dadurch ./index.html. Im Internet würde eine Verlinkung auf http://localhost/blog/index.html ja keinen Sinn machen.

Die Option -E sorgt dafür, dass die gespeicherten Seiten mit .html enden.

Mit -l 8 wird die Rekursionstiefe begrenzt. Es würde wahrscheinlich auch ohne diese Option gehen, ich wollte nur sicher gehen, dass wget nicht versucht, das gesamte Internet auf meiner Platte zu speichern.

Der Befehl wget ist ein extrem leistungsfähig. Einen kleinen Einblick, was man noch so alles damit anstellen kann, ist im Ubuntu-Wiki nachzulesen.

Nachdem wget ausgeführt wurde, liegt der komplette Inhalt des Blogs auf der Platte. Ein kleines Problem gibt es noch. Es existieren u. a. Dateien mit solchen Namen:

index.html?p=31.html

Lokal macht das nichts, diese Datei kann trotzdem im Browser aufgerufen werden. Anders sieht es jedoch auf dem Zielwebserver aus. Alles was hinter dem „?“ kommt wird als Argument interpretiert. Wenn ich im Browser also http://example.com/index.html?p=31.html aufrufe, dann wird http://example.com/index.html angezeigt und p=31.html wird der Seite als Argument übergeben. Damit kann diese Seite nichts anfangen.

Würde ich die Dateien so unbearbeitet auf den Zielwebserver hochladen, dann würde immer nur die Startseite des Blogs richtig angezeigt werden. Ein Klick auf einen Link zu einem Artikel würde wieder nur die Startseite aufrufen.

Deswegen müssen alle Dateien umbenannt werden, die ein „?“ im Namen haben. Damit nicht genug. Die Links in den lokalen Dateien, die auf Dateien mit einem „?“ im Namen zeigen, müssen ebenfalls geändert werden.

Fangen wir mit dem Umbenennen der Links an. Das „?“ möchte ich durch „_“ ersetzen. Das Fragezeichen speichert wget in den Links als _ ab. In einem Texteditor wäre es überhaupt kein Problem, mittels der Funktion Suchen und Ersetzen alle Vorkommen von _ durch _ zu ersetzen. Aber man möchte nicht wirklich mehrere hundert Dateien nacheinander im Editor öffnen und mittels Suchen und Ersetzen bearbeiten. Dafür gibt es den Befehl sed.

Die komplette Zeile im Skript sieht so aus:

find localhost -type f -print0 | xargs -0 -n 1 sed -i -e "s/_/_/g"

Mit sed -i -e "s/_/_/g" wird in einer Textdatei jedes Vorkommen von _ durch ein _ ersetzt.

Die Option -i sorgt dafür, dass die Datei überschrieben wird und das Ergebnis nicht an der Standardausgabe ausgegeben wird.

Mit -e wird ein Skript übergeben, das in diesem Fall nur auch "s/_/_/g" besteht. Das ist ein regulärer Ausdruck, der _ durch _ ersetzt.

Wie überzeuge ich aber nun sed, das für alle Dateien zu tun?

Dazu werden zunächst erst einmal alle Dateien aufgelistet. Das macht man mit find localhost -type f -print0.  Der Befehl find unter Unix und Linux unterscheidet sich vom find, das viele vielleicht von Windows her kennen. Hier eine Beschreibung dafür.

Die Option -type f sorgt dafür, dass nur Dateinamen und keine Ordnernamen aufgelistet werden. Mit -print0 werden die vollständigen Dateinamen ausgegeben mit einem Null-Zeichen als Trenner.

Über eine Pipe wird die Ausgabe von find an xargs übergeben. Dieser Befehl sorgt nur dafür, dass sed immer wieder mit der Ausgabe von findaufgerufen wird.

Damit ist das Korrigieren der Links in den Dateien erledigt. Es müssen nun noch die Dateien mit einem „?“ im Dateinamen umbenannt werden. Das passiert nach genau dem gleichen Schema:

find localhost -type f -print0 | xargs -0 -n 1 rename -v 's/\?/\_/' *

Der einige Unterschied zum Umbenennen der Links ist, dass jetzt statt sed jetzt rename aufgerufen wird.

Hier mein komplettes Skript:
#!/bin/bash
echo HTML-Seiten abspeichern
wget wget -r -k -E -l 8 http://localhost/blog/
echo #########################################
echo Links in den Dateien berichtigen
find localhost -type f -print0 | xargs -0 -n 1 sed -i -e "s/_/_/g"
echo #########################################
echo Dateinamen berichtigen
find localhost -type f -print0 | xargs -0 -n 1 rename -v 's/\?/\_/' *

Nach dem Ausführen des Skripts liegt nun ein Kopie des Blogs auf der lokalen Festplatte, die nun auf den Webspace hochgeladen werden kann. Das Hochladen ließe sich auch noch automatisieren. Ich wollte aber vorerst noch die Kontrolle behalten, was veröffentlicht wird.

Nachteile

Es gibt auch einige erhebliche Nachteile, wenn man nur statische HTML-Seiten auf dem Server hat. Es funktioniert natürlich keine Suchfunktion. Kommentarfunktion, Kontaktformulare, Foren usw. funktionieren nicht.

Wenn die lokale Wordpess-Installation nur auf den Arbeitsplatz-PC läuft, dann können auch nur auf diesen Computer Artikel geschrieben werden. Von eine beliebigen Computer im Internet mal schnell einen Blogbeitrag veröffentliche, das geht mit dieser Methode nicht.

Eine Sache sollte man bei dieser Methode nicht ganz außer acht lassen, das ist die Laufzeit des Skripts. Es ist sicherlich keine gute Idee, eine Seite mit mehreren tausend Unterseiten auf diese Art und Weise zu erzeugen. Sie ist eher für kleinere Projekte geeignet.

Weitere Anwendungen

Für das hier vorgestellte Verfahren gibt es noch einige weitere Einsatzszenarien. Überall da, wo eine WordPress-Seite offline zur Verfügung gestellt werden soll, kann es verwendet werden. Möchte man beispielsweise den Stand einer Seite einem Kunden vorstellen und es ist dort nicht sicher eine gute Internetverbindung vorhanden, dann ist dies ein Weg.

Oder muss ein USB-Stick für Werbezwecke produziert werden, dann sind mit WordPress sehr schnell die passenden Inhalten gestaltet. Beim Anwender es USB-Sticks kann man nicht davon ausgehen, dass eine Internetverbindung besteht. Und davon, dass man auf dem Computer des Anwenders gar einen kleinen Mini-Webserver starten kann, davon kann man erst recht nicht ausgehen.

Es lassen sich sicher noch einige Anwendungen mehr finden. Auf jeden Fall soll es kleine eine Anregung zum Experimentieren sein.

Übrigens: Unter der Haube jedes Mac läuft ein Unix. Unter MacOS kann man genau so wie unter Linux ein Terminal öffnen und das hier vorgestellte Skript ebenfalls ausführen.