Mein Blog    Projekte    Archiv    Impressum

CI-Pipeline für Blogposts

Ich betreibe inzwischen einiges an eigener Infrastruktur. Darunter eine Gitea Instanz unter git.avetter.net und eine Jenkins Instanz unter jenkins.avetter.net. Damit habe ich jetzt eine Pipeline gebaut, die automatisch den Jekyll-Build durchführt und das Ergebnis dann hier deployt.

Der passende Jenkins-Agent

Um die Builds durchführen zu können, war ein eigenes Docker-Image nötig, welches auch die nötigen Bibliotheken und Programme für meine eigenen Jekyll-Plugins enthält (z. B. ffmepg für das Video-Plugin). Da dieses Image gleichzeitig als Jenkins-Agent laufen soll, diente jenkins/ssh-agent als Basis-Image, welches über ein Dockerfile um Jekyll und die weitere nötige Software ergänzt wurde.

Nachdem dem mit dem Image erfolgreich lokal Jekyll-Seiten gebaut wurden, wurde es in der zentralen Docker-compose Konfiguration eingetragen. So läuft das Image als zusätzlicher Service. Es ist von außen nicht erreichbar, nur für den zentralen Jenkins-Server. Als der Agent dann in der Liste der Jenkins-Agenten auftauchte, ging es an die Einrichtung der Pipeline.

Details zu dem Image finden sich hier in meinem Repository.

Die Pipeline

Das Jekyll-Projekt, aus dem der Blog gebaut wird, liegt in einem Git-Repository. Für dieses ist ein Jekyll-Webhook konfiguriert, sodass bei Änderungen ggf. die Pipeline ausgeführt wird. Es gibt einen Staging-Branch, dessen Inhalt unter staging.avetter.net veröffentlicht werden. Hier kann ich Artikel anfangen, und mir eine live Vorschau ansehen. Wenn ein Artikel dann fertig ist, kann ich den Staging-Branch in den Main-Branch mergen, sodass die Hauptseite aktualisiert wird. Für die Anpassung der URLs in den Builds werden zwei zusätzliche config.yml Dateien verwendet. _config-main.yml und _config-staging.yml. In diesen steht nur Folgendes:

## note:
path: "https://blog.avetter.net"
url:  "https://blog.avetter.net"

Im Jenkinsfile stehen die Branch-abhängigen Build-Aufrufe:

stage('Main Building') {
    when {
        branch 'main'
    }
    steps {
        script {
            sh 'jekyll build --config _config.yml,_config-main.yml'
        }
    }
}

stage('Staging Build') {
    when {
        branch 'staging'
    }
    steps {
        script {
            sh 'jekyll build --config _config.yml,_config-staging.yml'
        }
    }
}

Außerdem entsprechende Deployment-Aufrufe, die die generierten, statischen Dateistrukturen in entsprechende Nginx-Container kopieren. Durch die Reihenfolge der _config.yml Dateien werden die path und url Variablen aus der Hauptkonfiguration überschrieben, während der Rest unverändert übernommen wird.

Anwendung

Der ganze Aufbau war zunächst natürlich einiges an Aufwand, aber auch eine schöne Fingerübung für die Entwicklung von CI-Pipelines. Und jetzt ist das Schreiben von Blogposts natürlich deutlich einfacher. Alles, was noch benötigt wird, ist ein Gerät mit Git und einem Texteditor. Keine lokale, aufwendig zu Pflegende Jekyll-Installation und kein Gefummel mit SFTP um die lokal erzeugte Seite auf den Webserver zu kopieren. Vielleicht schreibe ich dadurch ja jetzt wieder mehr Posts.