Migration zu Ghost

Ghost auf eigenem Server: Mein technisches Fundament

Ghost auf eigenem Server: Mein technisches Fundament
Eine Tafel des Interessanten: Publishing mit Ghost. © Gemini

Seit mehr als 15 Jahren lief diese Domain mit Wordpress. Seit zwei Wochen läuft das Publishing-System Ghost und ich habe eine Menge Erfahrungen gemacht. Was der Blick über den Tellerrand bewirkt beschreibe ich in dieser Artikelstrecke – kulturell, kognitiv und technisch.

Wie bereits berichtet, habe ich mich in einem längeren Prozess dazu entscheiden Wordpress zumindest in Frage zu stellen und ein anderes System zum Publishing zu nutzen. Meine Erfahrungen schreibe ich in dieser Strecke auf.

Schnelle Ergebnisse mit Docker

Um schnell Ergebnisse zu erzielen, habe ich den offiziellen Docker-Container von Ghost hochgefahren, eingerichtet und ganz eigene Probleme gehabt. Der Wechsel vom dateibasierten WordPress in einen Container war für mich überraschend und ungewohnt zugleich, und ich will gar nicht verschweigen, dass mein nächstes Ziel bereits feststeht: Der Übertrag der Daten zur Ghost-CLI, also weg vom Container. Zum Ausprobieren war Docker gut, doch wohl fühle ich mich damit nicht. Das soll diesen Teil aber nicht bestimmen, denn zunächst geht es darum, wie das System heute tatsächlich läuft und auf welchem Unterbau. Ein Technik-Artikel.

Der Server arbeitet auf Ubuntu, die Datenbank ist eine MariaDB, kein MySQL, und davor sitzt ein Nginx als Webproxy. Sicher ließe sich diese Konstellation verbessern, aber man arbeitet mit dem, was man hat. PHP ist gar nicht erst installiert, was Angriffsfläche und Pflegeaufwand zumindest an dieser Stelle senkt. 16 GByte Arbeitsspeicher stehen bereit, davon gestehe ich Ghost drei zu, darunter rechnet eine moderne AMD-EPYC-Server-CPU – ausgelastet wird das System also so gut wie nie. Auf ein Content Delivery Network, etwa von Cloudflare, habe ich vorerst bewusst verzichtet, weil die vorhandene Architektur genug abfängt, der Nginx-Cache großzügig greift und ich die Datenbankabfragen so klein wie möglich halte. Hoffentlich gelingt das auch mit Ghost.

Speicher als Dauerthema

Das eigentliche Dauerthema ist der SSD-Speicherplatz. Über fünfzehn Jahre haben sich Mediendateien angesammelt, Fotografien, kleinere Videos und vor allem umfangreiche Audioarchive, und dieser Bestand wächst. Platzmangel gab es zwar bisher nicht wirklich, aber ständig ein Backup auf dem Server zu haben ist viel. Ungefähr die Hälfte des Serverspeicherplatzes ist belegt, und das sollte jetzt mitgedacht werden, genau wie deutsche asymmetrische Internetleitungen, die große Datenmengen einfach zu einem Problem machen.

Hinzu kommt, dass die Migration den Bestand vorübergehend verdoppelt hat, weil die Mediendateien jetzt zweifach vorliegen – einmal im Wordpress und einmal als Kopie in Ghost. Hier hat es geholfen nur die Originale aus dem Wordpress zu kopieren, was in meinem Fall aber auch ein riesiger Datenberg ist.

Am Ende sind es trotzdem rund 50 GByte Medien, eben alles, was über die Jahre nicht verlorengegangen ist. Wer so plant, muss auch die Sicherungen entsprechend handhaben, doch das gehört in einen anderen Teil.

Modernes Medienhandling

Beim Bildhandling zeigt Ghost eine seiner angenehmen Seiten. Die benötigten Größen erzeugt es nämlich bei Bedarf über die eigene API, sodass im Theme keine aufwendigen Größendefinitionen mehr zu hinterlegen sind. Diese Entlastung empfinde ich als echten Mehrwert.

Ich habe für meine Archive immer die größtmögliche, detailreichste Speicherart gewählt, meist verlustfrei komprimiert, in den letzten Jahren verlustfrei komprimiertes WebP. Ob dieser Schritt unterm Strich wirklich etwas bringt, bleibt eine Grundsatzfrage. Entscheidend ist für mich ein anderer Punkt: Aus WordPress habe ich nur die Originaldateien übernommen, nicht die dort zusätzlich erzeugten Größen, und so kann Ghost aus der bestmöglichen Vorlage seine Ableitungen errechnen. Und das macht Ghost enorm schnell. Weil diese Ableitungen in einer eigens angelegten Ordnerstruktur liegen und nicht im gewöhnlichen Bildverzeichnis, lässt sich dort auch großzügig aufräumen. Beim erstmaligen Besuch geht die Auslastung natürlich nach oben, aber das ist nicht weiter schlimm.

Wenn der Upload stockt

Ein erwartbares Problem tritt beim gleichzeitigen Hochladen vieler hochauflösender Bilder auf, und manche meiner Originale messen dreißig Megabyte und mehr. Als ich meinen Cache-Warmer gestartet habe, ist Ghost beim ersten Versuch jedoch gescheitert, weil ich zu wenig Arbeitsspeicher zur Verfügung gestellt habe.

Der gesamte Server wurde für einige Minuten träge. Bemerkenswert ist, dass ich ihn dabei nie selbst neu starten musste, Ghost hat sich jedes Mal von allein wieder eingefangen. Unter WordPress führte vergleichbare Last durchaus zu Abbrüchen, in deren Folge Bilddateien fehlten, die ein Skript in meinem Theme regelmäßig prüfen und bei Bedarf neu erzeugen musste. Diese selbstgebaute Reparaturmechanik kann ich mir nun sparen – wieder ein Fallstrick weniger.

Der Cache-Warme ist einfach gestrickt. Er lädt die aktuelle Sitemap mit CURL und ruft jede Seite einmal mit niedriger Priorität ab, was zugleich die Erzeugung der Bildableitungen anstößt. Zwei Fliegen mit einer klappe: Der Cache ist da und die Bilder werden regelmäßig geprüft und bei Bedarf erstellt.

bash
#!/usr/bin/env bash
# cache-warmer: ruft jede URL der Sitemap einmal ab und stoesst dabei die Erzeugung der responsiven Bildgroessen an.

set -euo pipefail

SITEMAP="https://example.tld/sitemap.xml"

curl -s "$SITEMAP" \
  | grep -oE '<loc>[^<]+</loc>' \
  | sed -E 's#</?loc>##g' \
  | while read -r url; do
      curl -s -o /dev/null \
           -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)" \
           "$url"
      sleep 1
    done

Den Abruf erledigt ein Cronjob, der gezielt einen mobilen User-Agent vorgibt, damit auch die mobilen Bildvarianten entstehen. Hier könnt man optimieren, indem man den User von Googles Pagespeed Insights nutzt.

Ist Ghost schneller?

Ehrlich bleiben muss man beim Ertrag: Der Geschwindigkeitsgewinn im Browser des Endnutzers fällt gegenüber dem alten WordPress nicht dramatisch aus. Google Page Speed liefert je nach Seite stabil über den Tag etwa siebzig Punkte. Das ist solide, aber kein Triumph, denn der Weg war vorher ähnlich.

Die offenen Baustellen

Bei aller Zufriedenheit gibt es Fehlstellen, und drei davon wiegen für mich schwer.

Bilderverwaltung schwer gemacht

Enorm schwer wiegt für mich die fehlende Mediathek. Ghost kennt keine zentrale Medienverwaltung im Sinne der WordPress-Bibliothek, die Dateien leben in einer Ordnerstruktur, die ich selbst diszipliniert benennen muss, solange ich kein externes Verwaltungssystem dafür etabliere. Für jemanden, der ein großes Bild- und Audioarchiv pflegt, ist das spürbar und unübersichtlich.

Meine Podcasts

Die zweite Fehlstelle betrifft die Podcasts. Ich habe mir über die Jahre eine recht elaborierte Distributionsumgebung für Podcasts aufgebaut, und auch wenn ich sie nicht mehr so intensiv nutze, hänge ich emotional daran. Ghosts Kompatibilität mit Podcast-Feeds ist begrenzt, und so stehe ich vor der Entscheidung, ob ich das Hosting auslagere oder weiter selbst betreibe.

Seitenstruktur

Die dritte Umstellung ist struktureller Natur. Ich bearbeite im Kern drei große Themenfelder, die ich unter WordPress über Kategorien in saubere Silos sortiert und für strukturierte Ausgaben sowie die Benutzerführung genutzt habe. Ghost kennt nur Tags, keine Kategorien, und ob ich damit auf Dauer gut zurechtkomme, weiß ich noch nicht. Dynamische Landingpages, die diese Themenfelder eigenständig zusammenführen, habe ich in Ghost bislang nicht umgesetzt, und ich werde noch herausfinden müssen, wie sich das sinnvoll lösen lässt.

Sicherheitsstandards per 2FA und Mailserver

Bleibt der Punkt, der mich zu Beginn am meisten Mühe gekostet hat, der Mailserver. Lange hatte ich mich bewusst gegen einen eigenen Mailserverbetrieb entschieden, weil der Konfigurationsaufwand hoch und für kaum zu rechtfertigen ist. Ghost zwingt mich nun dazu, weil die Anmeldung über einen per E-Mail zugestellten Link erfolgt. Postfächer anlegen, die kryptografischen Signaturen für Domain und Mailserver einrichten, hier hat mir die Plesk-Serververwaltung viel abgenommen. Hier würde ich mir eine moderne TOTP-Integration wünschen. Da ist auch mehr als eine Fußnote, doch dazu werde ich in den kommenden Tagen mehr aufschreiben. Wenn der Mailserver klemmt ist der Zugriff nicht nur erschwert.