Featured image

Denkpass.de läuft in Hugo und deployed automatisch


Auf meiner Arbeit, bei alpha-board gmbh, einem Berliner Dienstleister für agile Hardware-Entwicklung und PCB-Design / Layouts, haben wir vor kurzem unsere Webseite mithilfe eines LLMs zu 11ty.dev portiert, und auch automatisches deployen mit Git-Actions eingerichtet.

Auf Arbeit nutzen wir Github Copilot und der hat das hingekriegt: ich schreibe eine Markdown-Datei in einem speziellen Ordner, pushe dann den ganzen Ordner nach git und dort wird es mit 11ty gebaut und danach auf https://alpha-board.de deployed.

Da habe ich mir gedacht, so eine coole Sache brauche ich auch für Denkpass.de, denn wenn es so einfach ist, blogge ich vielleicht öfter? Also habe ich mich mit Chat-GPT hingesetzt, um dieses Blog zu Static Site Generator Hugo zu portieren. Das lief gut, aber dies Blog ist ja auch recht simpel.

Probleme gab es, als ich nachts in meinem Editor zed irgendeine Tastenkombination betätigte und auf einmal in mehreren Dateien irgendwas einfügte und umher schob. Das hielt mich eine Weile auf und ich zweifelte schon langsam, ob ich das mit einem LLM wirklich hinkriege. Aber am Ende läuft es, wie man sieht.

Künftig fällt also Bloggen viel einfacher. Unter Umständen blogge ich dann also öfter.

Setup von Hugo

Der eigentliche Grund, von Jekyll abzuhauen war ja, dass mein LLM-Kumpel und ich Probleme hatten, das System zu updatem, weil eine Abhängigkeit bei Jekyll, die mit jekyll-feed zu tun hatte, auf meinem Silicon-Apple nicht installieren wollte. Da kam dann nach einer Weile die Idee auf, einfach nur die Blogposts, die in Markdown vorlagen, zu einem anderen Static Site Generator zu übertragen.

Die Installation Hugo ist einfach, s.Hugo Quick Start. Die Markdown-Blogposts aus Jekyll gingen einfach zu übertragen, nur am Frontmatter mussten wir arbeiten und haben dafür ein kleines Skript geschrieben (und ein Virtual Environment für Python aufgemacht, um das Skript auszuführen). Hier das Skript, dass Frontmatter von Jekyll anfässt und für Hugo umschreibt:

from pathlib import Path
import yaml

posts_path = Path("./content/posts")  # anpassen, falls nötig

for md_file in posts_path.glob("*.md"):
    content = md_file.read_text(encoding="utf-8")

    if content.startswith("---"):
        parts = content.split("---", 2)
        if len(parts) >= 3:
            _, front_matter_raw, body = parts
            try:
                front_matter = yaml.safe_load(front_matter_raw)

                # Felder anpassen
                front_matter.pop("layout", None)
                if isinstance(front_matter.get("tags"), str):
                    front_matter["tags"] = [front_matter["tags"]]
                elif isinstance(front_matter.get("tags"), list):
                    flat = []
                    for item in front_matter["tags"]:
                        if isinstance(item, str) and "," in item:
                            flat.extend([t.strip() for t in item.split(",")])
                        else:
                            flat.append(item)
                    front_matter["tags"] = flat
                if "date" in front_matter:
                    front_matter["date"] = str(front_matter["date"])

                # Neue Datei schreiben
                new_content = "---\n" + yaml.dump(front_matter, sort_keys=False) + "_

Hugo individualisieren mit CSS und eigenem HTML

Das hier ging eigentlich alles gut, bis ich meinen nächtlichen Editor-Tasten-Krieg erlebte und nichts mehr lief. Wir probierten rum, aber dabei war auch eine Datei (custom.css) in einem falschen Verzeichnis gelandet, wo sie nicht funktionierte. Nur brauchten wir eine Weile, bis das auffiel. Chat-GPT fragte irgendwann, ob ich sicher sei, dass diese Datei wirklich in diesem Verzeichnis liegt. Und da prüfte ich das im Finder statt in meinem Editor und sah es auf einmal.

Beim Aufsetzen eines Blogs mit Hugo kann man sich ein Hugo-Theme aussuchen. Das landet dann im Verzeichnis deiner Hugo-Seite unter /themes/name_deines_themes, in meinem Fall Whiteplain. Jetzt was Wichtiges: Wenn du was ändern willst, z.B. den Footer, dann kopierst Du die entsprechende Datei aus dem Theme (also z.B. themes/whiteplain/layouts/partials/footer.html) an den entsprechenden Ort in deinem Hugo-Verzeichnis, in diesem Fall /layouts/partials/footer.html. Dann kann sich das Theme aktualisieren, aber Hugo nimmt immer deine Kopie anstatt der des Themes.

Dasselbe gilt für custom.css. Wenn Du eine custom.css in /static/css/ erzeugst, überschreibt diese mit ihren Regeln alle vorher getroffenen CSS-Styles, z.B. aus dem Theme. So bleiben die CSS-Einstellungen, die dir wichtig sind, immer im selben File.

Automatisches Deployment via Netlify

Nachdem ich mein Hugo-Verzeichnis aufgesetzt, mit Blogposts gefüllt hatte, habe ich das ganze Verzeichnis zu Github gepusht. Dann habe ich auf Netlify einen kostenlosen Account eröffnet und dort ein neues Projekt mit meinem Github-Repository für Denkpass.de mit Hugo verbunden:

Git-Repository mit Netlify verbinden

  1. Logge dich bei Netlify ein.
  2. Klicke auf “Add new site” → “Import an existing project”.
  3. Wähle GitHub (oder GitLab/Bitbucket) und gib den Zugriff frei.
  4. Wähle das Repository mit der Hugo-Seite.
  5. Gib folgende Werte ein:
    • Branch to deploy: main oder master
    • Build command: hugo
    • Publish directory: public
  6. Klicke auf “Deploy site”.

Netlify baut nun die Seite bei jedem Push auf dein Repository automatisch neu.

Domain mit Netlify verbinden (z. B. denkpass.de)

Option 1 – Netlify verwaltet DNS (optional)

Wenn du möchtest, dass Netlify auch deine DNS-Zone verwaltet, musst du die Nameserver beim Domain-Provider umstellen:

Nameserver
dns1.p04.nsone.net
dns2.p04.nsone.net
dns3.p04.nsone.net
dns4.p04.nsone.net

Danach richtest du deine Domain direkt in Netlify ein und Netlify setzt die A/CNAME-Einträge selbst.

Option 2 - Beim Domain-Provider (z. B. Netcup, IONOS) DNS-Einträge setzen

Wenn du die DNS-Einträge selbst verwaltest (z. B. bei Netcup, IONOS, Cloudflare), gehst Du dort hin ins Setup und gibst diese Werte in dein DNS ein:

Typ Name Ziel
A denkpass.de oder leer 75.2.60.5
A denkpass.de oder *leer" 99.83.190.102
CNAME www dein-site-name.netlify.app (z. B. eiapopeia-salomina-8c6079.netlify.app)

Wichtig: Entferne alte A- oder CNAME-Einträge, die noch auf den vorherigen Hoster zeigen (z. B. 213.160.x.x). Einträge mit mail solltest Du aber stehen lassen.

Netlify-Einstellungen konfigurieren

Custom Domain einrichten:
  1. Gehe in Netlify zu: Site Settings → Domain Management
  2. Klicke auf “Add custom domain”
  3. Trage denkpass.de ein und bestätige
  4. Klicke auf “Verify DNS configuration”

Das kann eine Weile dauern, also geduldig bleiben. Bei mir wurde alles in nicht mal einer Stunde übertragen.

HTTPS aktivieren:

Nach erfolgreicher DNS-Prüfung erscheint die Option:

“Provision certificate”

Klicke darauf, um ein kostenloses SSL-Zertifikat (Let’s Encrypt) und somit auch https zu aktivieren. Netlify kümmert sich danach automatisch um die Verlängerung des Zertifikats.

Noch offen

Hier stehen ein paar Punkte, die noch in Bearbeitung sind. Wir haben nicht alles geschafft und irgendwann wollte ich einfach was posten und deployen.

VENV, neue Fonts, etc.

Damit Frontmatter geändert werden konnte, liessen wir ein Python-Skript laufen. Dafür haben wir auch ein Virtual Environment aufgesetzt, dass auch gegitted wurde (auch wenn wir eigentlich keine Frontmatter mehr importieren wollen).

Ich fand, ich wollte schon immer mal ein Blog mit einem Monospace-Font haben und habe mich für Fira Code entschieden.

Wir haben auch eine Readme.md aufgesetzt, die als Impressum fungiert. Damit sie im Blog nicht zuoberst angezeigt wird (sondern nur in der oberen Menüleiste), habe ich sie weit zurück datiert. So wird sie nun irgendwo unter allen Posts angezeigt, falls da mal jemand hinscrollt.