Statische Webseite bauen und deployen mit KISS
Im letzten Blogpost habe ich mir bereits die Verwendung von Decap CMS als Admin Interface für meine Jekyll Webseite angeschaut und dies implementiert. Im selben Zug habe ich auch eine Möglichkeit implementiert um die Webseite zu aktualisieren und dazu einen Post versprochen.
Bisher hatte ich auf meinem Uberspace lediglich ein Verzeichnis mit den Source-Daten meiner Webseite. Dieses habe ich händisch aktualisiert und anschließend ebenfalls händisch gebaut. Da Decap CMS aber eh ein git Repository benötigt habe ich das Verzeichnis in ein git Repository konvertiert, da dieses eh für Decap CMS benötigt wird. Da die Daten schon versioniert vorliegen, wollte ich die Aktualisierung der Website ebenfalls automatisieren, hierfür aber eine einfache Lösung finden. Hier ist das KISS Prinzip immer wieder ein guter Ansatz. Jeder der folgenden Teile ist in sich einfach und schnell zu durchdringen, so das der gesamte Prozess simpel ist.
Um nun das Git Repository von Forgejo zu Uberspace zu übertragen gibt es in den Einstellungen zum Repository die Option ein Push Spiegelserver einzurichten. Hier kann per ssh eine URL angegeben werden, auf die das Repository bei Änderungen automatisch gepushed wird. Auf meinem Uberspace (als Ziel) muss hierfür auch kein git Server laufen, da git auch mit ssh und Pfaden arbeiten kann. Um die ssh Authentifizierung abzubilden kann Forgejo automatisch ein ssh Schlussel erzeugen, der dann für den Push genutzt wird. Zu diesem kann man sich den öffentlichen Schlüssel einfach kopieren, um ihn auf dem Ziel zu hinterlegen. Eine sehr schöne Lösung finde ich.
Bei einer Änderung im Repository, welche zum Beispiel über Decap CMS durchgeführt wurde, werden die Änderungen so automatisch auf das Repository im Uberspace übertragen.
Da nun das Repository auf Uberspace aktuell ist muss nur noch der Inhalt neu gebaut und deployed werden um die Webseite zu aktualisieren.
Für das Bauen wird der Befehl jekyll build verwendet. Dieser führt auch gleich das Deployment durch indem in der config die Option destination gesetzt ist.
Um den erforderlichen Befehl auszuführen ohne zusätzliche extra Infrastruktur zu benötigen, lassen sich git hooks verwenden. In meinem Fall der post-receive-Hook. Um diesen zu verwenden wird im Verzeichnis .git/hooks eine Datei mit dem Namen des Hooks angelegt und diese ausführbar gemacht.
#!/bin/bash -l
set -x
exec 1>"$HOME/logs/jekyll_build.log"
exec 2>&1
cd ..
date
pwd
unset GIT_DIR
git reset --hard
bundle install
bundle exec jekyll build
Wie man sieht macht das Skript noch mehr als nur den erwarteten build. Dies ist notwendig um das Arbeitsverzeichnis des Repository in den aktualisierten Zustand zu bekommen. Der erste Abschnitt ist lediglich um sowohl stdout als auch stderr in eine Logdatei zu schreiben. Anschließend müssen wir in das übergeordnete Verzeichnis wechseln, da das Skript im .git-Order ausgeführt wird. Daraufhin wird die Variable GIT_DIR entfernt und mit git reset --hard das Arbeitsverzeichnis auf den aktuellen Stand des aktualisierten Indexes hoch gezogen. Hierbei werden alle Änderungen verworfen was normalerweise unerwünscht sein kann, hier aber Absicht ist, damit man immer einen bekannter und aktualler Zustand existiert. Zu guter Letzt werden die Abhängigkeiten installiert und final der Build ausgeführt.
Dieser baut die statische Webseite und stellt sie im Webroot des Webservers bereit.