Workflow für die Erstellung und Pflege von Webseiten
Ich stelle die von mir betriebenen Webseiten, die nicht auf interaktive Funktionen angewiesen sind, Stück für Stück auf statisch generierte Seiten um, zuletzt meine Homepage. Dabei setze ich auf einen Workflow, der nanoc als static site generator und git als Versionsverwaltungssystem umfasst und dafür sorgt, dass Änderungen der Seiten automatisch eingespielt werden.
Entwicklung, Test und Veröffentlichung
Bei Verwendung eines static site generators werden die Webseiten zunächst aus Quelldateien erzeugt und müssen dann veröffentlicht, d.h. in das passende Verzeichnis des Webservers befördert werden, der sie anzeigen soll. Darüber hinaus ist es generell sinnvoll, “Code” im weitesten Sinne - und dazu gehören dann auch HTML- und CSS-Dateien bzw. die Quellen, aus denen diese erzeugt werden - in einem Versionsverwaltungssystem zu speichern, in dem Änderungen nachverfolgbar sind und wo jederzeit auf ältere Versionen zurückgegriffen werden kann. Nimmt man dies zusammen, unterscheiden sich Webseiten damit letztlich kaum mehr von Webapplikationen oder anderer Software: es gibt den Quellcode und das Kompilat (die fertigen Seiten, das ablauffähige Programm), Quellcode muss verwaltet und das Ergebnis getestet und schließlich veröffentlicht (deployed) werden.
Für die drei Schritte - entwickeln, testen, veröffentlichen - werden zumeist mehrere Rechner (Systeme, Umgebungen) benötigt, die unterschiedlichen Zwecken dienen:
Entwicklungsumgebung
Der Rechner, auf dem die Seiten entworfen, bearbeitet und ggf. auch getestet werden.Git-Server
Git ist zwar ein verteiltes Versionsverwaltungssystem, aber es ist generell sinnvoll, das Repository nicht nur auf dem eigenen Arbeitsrechner vorzuhalten, sondern auch auf (mindestens) einem Server. Das schafft Redundanz und ermöglicht es, auf verschiedenen Rechner zu arbeiten und die Ergebnisse jeweils zu synchronisieren.Testumgebung
Es ist sinnvoll, ein Testsystem vorzuhalten, dass dem Echtsystem weitgehend entspricht, um testen zu können, ob die Webseiten auch wirklich so aussehen und “funktionieren”, wie man sich das vorstellt.Echtumgebung
Am Ende des Tages sollen die Webseiten auf einem Rechner im Netz liegen, der sie mithilfe eines Webservers weltweit abrufbar macht.
Grundsätzlich kann man das alles auf ein- und demselben Gerät betreiben: eine im Netz verfügbare Maschine, auf der man sich einloggt und entwickelt, auf der Git verfügbar ist und die zugleich Test- und Echtumgebung darstellt. Meistens wird man aber doch auf dem heimischen Desktoprechner oder dem Laptop arbeiten wollen und einen Webserver (oder auch nur Webspace) irgendwo angemietet haben. Letzteres gilt auch für mich.
Mein Workflow
Ich bearbeite die Quelldateien (den Sourcecode) meiner Webseiten auf meinem Desktoprechner oder dem Laptop unter Windows, zumeist mit Sublime Text, reine Markdown-Dateien manchmal auch mit MarkdownPad.
nanoc unterstützt einen sehr bequemen Testmodus mit eingebautem Webserver: nach dem Compilieren mit nanoc
genügt ein nanoc view
, um einen Webserver zu starten, der dann unter http://localhost:3000/
die Website zur Ansicht bereitstellt. Leider funktioniert das für mich noch nicht, denn zwar lässt sich nanoc grundsätzlich auch unter Windows installieren und betreiben, aber das für den LESS-Filter erforderliche Ruby-Gem leider nicht - jedenfalls ist mir das nicht gelungen. Daher arbeite ich weiterhin “nach alter Väter Sitte” und lade die geänderten Dateien per SCP bzw. SFTP entweder auf einen lokalen Linux-Server oder direkt auf den externen Webserver hoch bzw. sorge für eine automatische Synchronisierung mit WinSCP. Dort wird dann compiliert und im Browser das Ergebnis angeschaut.
Auch das Veröffentlichen der Seiten unterstützt nanoc mit dem Kommando nanoc deploy
, das ein Deployment per git, per rsync oder mittels fog unterstützt. Das ist sicherlich sehr nützlich, wenn man die Webseiten auf dem Entwicklungsrechner testet und dann von dort auf den Webserver überspielt; nachdem nanoc aber auf meinen Windows-Rechnern nicht läuft, gehe ich einen anderen Weg und compiliere direkt auf dem Webserver. Ich lade also den Quellcode hoch, lasse nanoc auf dem Server laufen und das Ergebnis dann unmittelbar in das Webserver-Verzeichnis ausgeben (in der Regel durch ein passend gesetztes output_dir
in der nanoc.yaml
).
Ich halte regelmäßig neben der aktuellen Fassung meiner Webseiten auch eine Testfassung vor, die ich über eine passwortgeschützte URL aufrufen kann. Das hat den Vorteil, dass ich von überallher testen kann und zudem die Testumgebung und die Echtumgebung identisch sind, weil sie auf demselben Server (in zwei unterschiedlichen virtual hosts) laufen.
Das jeweilige Git-Repository für eine Website hat daher immer mindestens den master- und einen staging-Zweig; im letzteren wird getestet, der erstere enthält die aktuelle Echtversion. Wenn ich einen dieser Zweige per git push
auf meinen Git-Server schiebe, wird er automatisch auf den Webserver kopiert (in das Quellverzeichnis für die Echtfassung oder dasjenige für die Testversion der Website), dort compiliert und bereitgestellt. Auch für dieses “Kopieren” oder generell das Aktualisieren einer Website über git gibt es eine Reihe von Möglichkeiten: man kann bspw. einfach das Git-Repository auf dem Webserver auschecken, oder aber man checkt via git archive
wirklich nur den Inhalt des Repositorys aus. Ich habe mich für letzteres entschieden; einziger Nachteil ist, das aus dem Repository entfernte Dateien nicht automatisch gelöscht werden, ggf. also “Leichen” verbleiben. Dafür habe ich nicht das komplette Repository mit der ganzen History herumliegen.
Ein Beispiel
In der Praxis sieht das dann ungefähr so aus:
Ich aktualisiere mein lokales Git-Repository auf dem jeweiligen Arbeitsrechner, damit es auf dem aktuellen Stand ist.
Ich verändere oder ergänze meine Webseiten, indem ich die entsprechenden Dateien auf dem Arbeitsrechner bearbeite.
Wenn umfangreichere Tests erforderlich sind, lade ich die geänderten Dateien auf meinen Webserver in das Quellverzeichnis für die Test-Instanz der jeweiligen Website hoch und führe - auf dem Server - nanoc aus, so dass die Testinstanz der jeweiligen Webseiten aktualisiert wird. Im Browser kann ich dann die geänderten Seiten durch Aufruf von
http://test.meine-website.example/
ansehen. Alternativ kann ich natürlich auch auf einem anderen Rechner im lokalen Netz testen.Wenn ich mit dem Ergebnis zufrieden bin, aktualisiere ich den test-Zweig meines lokalen Git-Repositorys und schiebe ihn per
git push
auf den externen Git-Server.
Dort wird ein post-receive
-Hook ausgeführt, der auf dem richtigen Webserver ein PHP-Script mit den passenden Paramtern aufruft. Das Script sorgt dann dafür, dass die Dateien aus dem Git-Repository ausgecheckt werden, und führt danach nanoc aus. Für den test
-Zweig des Repositories websites/meine-website
auf dem Server git.server.example
mit dem Zielverzeichnis /var/www/sources/meine-website/
auf dem Webserver sähe das dann so aus:
$ git archive --format=tar --remote=ssh://git@git.server.example/websites/meine-website test | tar -C /var/www/sources/test.meine-website.example/ -xf -
$ cd /var/www/sources/test.meine-website.example/
$ nanoc
nanoc hat dann als output_dir
bspw. /var/www/html/test.meine-website.example/
konfiguriert, was zugleich das DocumentRoot
für den virtual host http://test.meine-website.example/
ist.
- Will ich später die gesammelten Änderungen aus der Testinstanz auf die Echtinstanz übernehmen, geht das ebenfalls ganz einfach: ich bringe sie in den master-zweig meines Repositorys und veröffentliche diesen:
git checkout master; git merge test; git push; git checkout test
Der post-receive
-Hook wird das Deployment-Script mit anderen Parametern aufrufen, so dass nicht der test-Zweig, sondern der master-Zweig ausgecheckt und nicht nach /var/www/sources/test.meine-website.example/
, sondern nach /var/www/sources/www.meine-website.example/
kopiert wird. Und das ist dementsprechend das DocumentRoot
für http://www.meine-website.example/
.
Die nanoc-Ausgaben gibt das Deployment-Script aus, so dass der Git-Server sie an den Git-Client übermittelt; sollte nanoc die Compilation also mit einer Fehlermeldung abbrechen, ist das erkennbar und ermöglicht ein manuelles Eingreifen. Ansonsten sind manuelle Eingriffe nur noch erforderlich, wenn eine bereits deployte Datei gelöscht werden muss; es liegt in der Natur der Sache, dass der gewählte Weg über git archive
neue und geänderte Dateien (und Verzeichnisse) anlegt, alte Dateien aber nicht löscht.
Conclusio
Viele Wege führen nach Rom; dies ist meiner.
Er lässt sich fraglos vereinfachen; ein Hemmschuh ist insbesondere die Entwicklung unter Windows, die den Workflow erschwert.
Kommentare und Kritik nehme ich gerne entgegen, ebenso wie andere Wege zum selben Ziel.
Kommentare
Ansicht der Kommentare: Linear | Verschachtelt