Website Deployment mit Codeberg Pages und CI
Wer mit dem Static-Site-Generator Hugo seine Webauftritt erstellt, will die generierten Webseiten auf einem Server bereitstellen: Irgendwo einen Webspace besitzen, Markdown-Dateien bearbeiten, hugo
ausführen und im Anschluss per scp
die Dateien im Hugo-Projekt aus dem Unter-Verzeichnis public
hochladen. Das ist kein Hexenwerk, aber von der Bearbeitung des Inhaltes bis zur Bereitstellung auf dem Webspace sind einige Schritte notwendig. Insbesondere bei kleinen Änderungen kann das nervig sein.
Da ich für meinen Teil sehr gerne mit git
arbeite und meine Quellen in der Regel auf irgendwelchen gitea-/forgejo-Instanzen verteile, habe ich mich bei dieser Website dafür entschieden, Codeberg Pages für das Hosting zu verwenden. Darüber hinaus automatisiere ich den Build- und Deploy-Prozess mit Hilfe von Codeberg CI. Wie das im Detail geht, beschreibe ich im Folgenden.
Inhalt:
Es gibt zwei Repos auf Codeberg:
- toheine_sources enthält das Hugo-Projekt. (Quellen-Repo)
- toheine enthält die durch Hugo generierten Dateien für den Webserver. (Pages-Repo)
Das Hugo-Projekt ist wie folgt aufgebaut:
. -> Quellen-Repo
├── archetypes
├── assets
├── content
├── data
├── layouts
├── public -> Pages-Repo
├── resources
├── static
└── themes
Damit liegt ein Repo in einem Repo. Das ist kein Problem, da git
hierfür eine Lösung gleich liefert: git submodule
Jedes Mal, wenn Änderungen im Hugo-Projekt (im Quellen-Repo) durchgeführt werden, wird im Anschluss ein Commit erzeugt und in mein Codeberg-Repo gepusht toheine_sources. Dieses Event wird von der Codeberg CI registriert, der dort verwendete Woodpecker beginnt die Hugo-Files zu bauen und hinterlegt die so erzeugten Dateien im Pages-Repo toheine. Letzteres nutzt Codeberg Pages, der die Dateien unter einer Domain als Webseite bereitstellt.
In einem ersten Schritt habe ich auf Codeberg die beiden öffentlichen, leeren Repos erstellt. Wichtig: Damit die Webseite von Codeberg Pages später korrekt dargestellt wird, lautet der Name des einzigen Branches im Webseiten-Repo “pages”.
Beim Quellen-Repo ist der Name des/der verwendeten Branches egal. Auf dem Rechner habe ich dann das Quellen-Repo heruntergeladen und mein (bereits vorhandenes) Hugoprojekt dort hinein kopiert:
git clone git@codeberg.org:toheine/toheine_sources.git
cd toheine_sources
cp -r /Quelle/meines/Hugo-Projektes/* .
Im Anschluss hab ich das Public-Verzeichnis entfernt und das Submodul hinzugefügt:
rm -rf public
git submodule add git@codeberg.org:toheine/toheine.git public
Die Struktur meiner Git-Repos ist somit fertig und die Webseite kann via https://toheine.codeberg.page/toheine/ aufgerufen werden (Aufbau: https://<user>.codeberg.page/repo
). Ich will allerdings meine eigene Domain verwenden. Das ist hier auch gut dokumentiert. Ich habe mich für Option 2 (via ALIAS record) entschieden und folgende DNS-Einträge vorgenommen:
Domain Type Data
toheine.net ALIAS codeberg.page
toheine.net TXT toheine.toheine.codeberg.page
www.toheine.net CNAME toheine.net
Im letzten Schritt brauche ich in meinem pages-Repo noch eine Datei .domains
, die pro Zeile einen Eintrag mit allen Adressen enthält, über die ich meine Seite aufrufen will. Diese hat in meinem Fall folgenden Aufbau:
toheine.net
www.toheine.net
Der Pages-Server von Codeberg sorgt jetzt dafür, dass die Seiten korrekt angezeigt werden und hinterlegt ein passendes Lets-Encrypt-Zertifikat:
Ab jetzt kann ich manuell (ohne CI) neue Seiten veröffentlichen, in dem ich nach einer Änderung an meinem Hugo-Projekt lokal hugo
ausführe, dann in das Verzeichnis public
navigiere und die dortigen Änderungen in mein Pages-Repo auf Codeberg pushe:
hugo
cd public
git add *
git commit -m "Manuelle Änderung meiner Hugo-Seite"
git push
Es fehlt noch der Schritt zur Automatisierung via Codeberg CI. Dieses System kann allerdings nicht ohne Anmeldung benutzt werden. Es muss vorab ein Request gestellt werden. Das Verfahren ist unter folgender Adresse beschrieben: https://codeberg.org/Codeberg-e.V./requests.
Nachdem ich das Issue erstellt hatte (siehe hier), erfolgte wenige Stunden später eine Freigabe und damit Zugriff auf Codeberg CI via https://ci.codeberg.org/. Der Login erfolgt via SSO: Wer auf Codeberg angemeldet ist, klickt auf “Anmelden” und kann loslegen:
Über den Button “Repository hinzufügen” wählt man das Quellen-Repo aus und klickt auf “Aktivieren”. Wenn das hinterlegt ist, brauchen wir noch eine Pipeline im Quellen-Repo, dass den Namen .woodpecker.yml
trägt. Letztendlich ist das die Abfolge an Befehlen, die von der Codeberg CI (Woodpecker) ausgeführt wird, sobald eine Änderung auf Codeberg erfolgt. Freundlicherweise, liegen für viele erdenkliche Szenarien schon Beispiele bereit (siehe hier).
Ich hab die Datei für meine Verwendung leicht angepasst, aber im Wesentlichen so beibehalten (siehe hier). Wichtig ist allerdings, dass bei Verwendung die Codeberg CI die beiden Variablen mail
und codeberg_token
gesetzt werden. Den Token müssen wir vorab im Codeberg-Konto generieren:
Hierzu muss in den Profil-Einstellungen, unter Anwendungen, ein Zugriffstoken hinzugefügt werden. Dieser bekommt einen eindeutigen Namen und entsprechende Berechtigungen:
Soblad man auf “Token generieren” klickt, erscheint der Token mit einem Hinweis, diesen jetzt zu kopieren, da er später nicht mehr angezeigt wird.
Im letzten Schritt der Einrichtung hinterlegen wir die beiden oben erwähnten Secrets noch in Woodpecker. Dazu im Repo (also auf https://ci.codeberg.org/), in den Einstellungen …
… unter dem Reiter “Geheimnisse” die beiden gewünschten Werte hinterlegen:
Damit ist Woodpecker (Codeberg CI) fertig eingerichtet.
So … da in Zukunft eigentlich nur noch im Quellen-Repo gearbeitet wird und die Erzeugung nicht mehr lokal erfolgt, ist der lokale Ordner public
im Hugo-Projekt für die Versionierung nicht mehr relevant. Daher hab ich diesen auf die Ignore-Liste gesetzt:
echo public >> .gitignore
Wenn Änderungen im Hugo-Projekt durchgeführt und versioniert werden, bekommt das Woodpecker mit. Codeberg CI erstellt die Seiten und veröfffentlicht diese auf Codeberg Pages. Wenn man nach einem commit, das Projekt in das Quellen-Repo auf Codeberg pusht, kann man den Prozess in der Woodpecker-Webui verfolgen:
Sobald der Specht anfängt zu klopfen …
… kann der Prozess im Detail eingesehen werden, in dem man auf die Commit-Botschaft klickt. Die einzelnen Schritte werden abgearbeitet und können in den “Step Logs” nachvollzogen werden:
Sofern alles korrekt gelaufen ist, erscheint ein grüner Haken pro einzelnem Schritt und nach Fertigstellung für den ganzen Commit:
Es ist ein wenig Aufwand, diese hier erwähnte Automatisierung mit Woodpecker zu realisieren. Aber … wenn das System eingerichtet ist, ist die Veröffentlichung in Sekunden realisiert und auch kleinere Änderungen an der Webseite sind schnell erledigt. Daher war das IMHO eine sinnvolle Investition.
Darüber hinaus hat man als Lehrkraft oder in der Fortbildung gleich ein Beispiel für einen sinnvollen Einsatz von CI/CD.
Codeberg e. V. bietet neben den reinen git-Repos mit Codeberg Pages und Codeberg CI ein überragendes Angebot. Die Doku und die erwähnten Beispiele für die.woodpecker.yml
lassen keine Wünsche übrig. Ich finde das der absolute Hammer und Codeberg ist ein toller Verein!!!