In Teil 1 habe ich erklärt wie das OS-Repository das Gehirn von Phantom Grid ist. In Teil 2 waren die KI-Entitäten dran. Jetzt wird es technisch — die Pipeline die dafür sorgt, dass ein git push in der Webseite landet.
Die kurze Version: Astro 6 liest Daten aus dem OS-Submodule, Docker baut ein schlankes nginx-Image, GitHub Actions pusht es nach ghcr.io, ArgoCD deployt es automatisch auf meinem k3s-Cluster. Ende zu Ende.
Das Framework: Astro 6
Die Wahl fiel auf Astro aus einem einzigen Grund: ich brauche nicht unbedingt JavaScript im Browser, auch wenn ich es eigentlich mag, damit zu entwickeln und zu bauen.
Phantom Grid ist zunächst eine statische Seite. Kein Warenkorb, kein Login, keine Real-Time-Daten. Astros Island-Architecture passt perfekt — Components werden zur Build-Zeit gerendert, das Ergebnis ist reines HTML und CSS. Was im Browser landet ist minimal.
Ein weiteres Argument: Astro kann direkt JSON oder Markdown-Dateien aus dem Filesystem lesen. Die Release-Daten im OS-Submodule — jede Release hat eine release.json mit Catalog-Nummer, Artist, Tracklist, Links — werden beim Build automatisch zu statischen Seiten. Kein CMS, kein API-Call. Der Build liest die Dateien, generiert die Seiten, fertig.
phantom-grid-os/releases/pg-001-.../release.json
→ Build-Zeit: Astro liest die Datei
→ Output: /releases/pg-001/index.html
Das Dockerfile: zweistufig, schlank
Das Dockerfile folgt einem Muster das ich bei allen meinen statischen Sites nutze: Multi-Stage-Build.
# Build stage
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# Runtime stage
FROM nginx:alpine
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080
Der erste Stage installiert Dependencies, baut das Projekt. Der zweite Stage nimmt nur das dist/-Verzeichnis mit — kein Node, keine node_modules, kein Build-Tooling im finalen Image. Das Ergebnis ist ein nginx:alpine-Container der statische Dateien ausliefert. Kleiner, schneller, Angriffsfläche minimal.
Die nginx-Konfiguration läuft auf Port 8080 — das ist der Standard in meinem Cluster — mit aktiviertem gzip und einem /healthz-Endpoint für die Kubernetes-Probes.
GitHub Actions: das kritische Detail
Die Build-Pipeline ist straightforward. Trigger bei Push auf main, Login in die GitHub Container Registry, Image bauen und pushen.
Ein Detail ist aber entscheidend und wird gerne vergessen:
- uses: actions/checkout@v4
with:
submodules: recursive
Ohne submodules: recursive checkt GitHub Actions das phantom-grid-os-Submodule nicht aus. Der phantom-grid-os-Ordner ist beim Build leer. Astro findet keine Release-JSON-Dateien. Der Build schlägt fehl — oder schlimmer: er läuft durch und erzeugt eine Seite ohne Content.
Das ist kein hypothetisches Szenario. Ich habe es beim ersten Deploy erlebt. Der Fehler war nicht offensichtlich weil der Build selbst durchgelaufen ist — Astro hat keine Dateien gefunden und deshalb auch keine Fehler geworfen, nur keine Seiten generiert.
submodules: recursive gehört in jede GitHub-Actions-Pipeline die mit Submodulen arbeitet. Immer. Ohne Ausnahme.
ArgoCD: GitOps als Deployment-Modell
Das fertige Image landet in der GitHub Container Registry unter ghcr.io/tobeworks/phantom-grid-web:latest. Von dort übernimmt ArgoCD.
ArgoCD ist ein GitOps-Controller für Kubernetes. Das bedeutet: der gewünschte Zustand des Clusters ist in einem Git-Repository definiert. ArgoCD gleicht den tatsächlichen Cluster-Zustand laufend mit dem Repository ab und sorgt dafür dass beides übereinstimmt.
Für Phantom Grid heißt das: in meinem netcup-Repository liegt eine phantom-grid-web.yaml die beschreibt wie das Deployment aussehen soll — welches Image, wie viele Replicas, welche Domain. Wenn ich ein neues Image pushe, erkennt der ArgoCD Image Updater den neuen Digest und aktualisiert das Deployment automatisch.
git push phantom-grid-web
→ GitHub Actions baut Docker Image
→ ghcr.io/tobeworks/phantom-grid-web:latest aktualisiert
→ ArgoCD Image Updater erkennt neuen Digest
→ Cluster deployt neue Version
→ phantom-grid.de live ✓
Kein manuelles kubectl apply. Kein SSH auf den Server. Kein Deployment-Script das ich irgendwo aufbewahren muss. Der Push ist das Deployment.
Die Geburt — zwei Minuten von null zu live
Ich muss kurz innehalten und von dem Moment erzählen der Phantom Grid von einem Konzept zu einem real existierenden Ding gemacht hat.
Bevor die Astro-Site existierte, hatte ich die Coming-Soon-Seite — das HTML das direkt im Kubernetes ConfigMap lag. Der Plan war klar: dieses visuelle Fundament in eine richtige Astro-Site überführen, mit Docker und ArgoCD deployen.
Ich habe einem KI-Agenten gesagt: ich will ein nginx-Image in ArgoCD deployen, ich nutze Kubernetes, hier ist das lokale Repo.
Das war der komplette Prompt.
Was danach passierte war vollständig automatisiert. Das Dockerfile wurde generiert. Die GitHub Actions Pipeline wurde aufgesetzt. Die ArgoCD-Manifeste — Deployment, Service, Ingress, Namespace, Middleware — wurden geschrieben und in das Cluster-Repository committed. Das Image wurde gebaut und nach ghcr.io gepusht. ArgoCD hat synct.
Das einzige was ich manuell gemacht habe: den A-Record auf die Server-IP setzen.
Zwei Minuten später war phantom-grid.de live — inklusive Let’s Encrypt-Zertifikat, HTTPS-Redirect, www-Redirect. Vollständig.
Das war der echte Geburtmoment von Phantom Grid. Nicht der erste Commit. Nicht das erste Design. Der Moment wo ein Prompt zu einer live deployeten Website mit SSL-Zertifikat wurde — und ich dabei zugeschaut habe.
Das ist der Proof of Concept den ich gesucht hatte. Nicht ob KI Code schreiben kann. Sondern ob die vollständige Infrastruktur eines kulturellen Projekts in einem einzigen automatisierten Prozess entstehen kann. Die Antwort ist ja.
Das Zusammenspiel: zwei Repos, eine Pipeline
Was ich an diesem Setup besonders mag ist wie die Zwei-Repos-Architektur aus Teil 1 in der Pipeline konkret wird.
Wenn ich eine neue Release im OS committte und pushe, passiert erstmal nichts auf der Webseite. Das OS lebt in seinem eigenen Zyklus. Erst wenn ich im Web-Repo den Submodule-Pointer weiterbewege — drei Befehle — läuft die Pipeline und die neue Release-Seite ist live.
git submodule update --remote
git add phantom-grid-os
git commit -m "chore: update OS — PG-002 live"
git push
Das ist bewusste Kontrolle über den Release-Zeitpunkt. Das OS kann weit voraus sein — Releases vorbereitet, Artwork beschrieben, Tracklist final. Die Webseite zeigt trotzdem nur das was ich freigegeben habe.
In der Musikindustrie nennt man das Embargo. In der Softwareentwicklung nennt man das Feature Flag. Das Prinzip ist dasselbe.
In Teil 4 geht es um das Design System — wie Terminal Glow, VHS-Glitch, Scanlines und Phosphor Glow von einer HTML-Idee zu einem dokumentierten visuellen System wurden das als CSS-Bibliothek und Post-Production-Tool gleichzeitig existiert.
Kommentare