aj-printstudios.de

Statische Visitenkarte für eine Werkstatt in der bayrischen Rhön. Astro, Cloudflare Tunnel, Self-Hosting auf einem HP T630 Thin Client.

Astro Tailwind Cloudflare Tunnel Caddy Self-Hosting
aj-printstudios.de Vorschau

Was es ist

Eine Visitenkarte für Anne, die in der bayrischen Rhön Lasergravuren und 3D-Druck macht. Eine Frau, drei Maschinen, eine Werkstatt. Die Site soll das transportieren, ohne in Marketing-Sprech zu kippen: kein “Vision”, kein “Ihre Lösung”, einfach was sie tut, wie sie arbeitet, wie man sie erreicht.

Live anschauen kann man sie unter aj-printstudios.de.

Warum statisch

Bei einer Site die in fünf Jahren noch genauso laufen soll wie heute, ist eine Datenbank vor allem eine zukünftige Wartungsbaustelle. Kein WordPress, kein Plugin-Hell, kein “Ihre Datenbank wurde geupdatet, bitte einloggen und verifizieren” alle drei Wochen.

Stattdessen: HTML, CSS, Bilder. Statisch, schnell, sicher. Generiert wird einmal beim Bauen, ausgeliefert wird der fertige Output. Es gibt schlicht nichts, was zur Laufzeit gehackt werden kann, weil zur Laufzeit nichts läuft.

Was drunter steckt

  • Astro als Static Site Generator. Markdown-Inhalte, Komponenten in Astros eigenem .astro-Format, alles wird zur Build-Zeit zu fertigem HTML kompiliert.
  • Tailwind CSS für das Styling.
  • Astros Image-Pipeline wandelt Fotos automatisch nach WebP um und liefert verschiedene Auflösungen für unterschiedliche Bildschirme aus. Das hilft den Lighthouse-Werten und spart Traffic.
  • astro-icon mit Tabler-Set für die paar Icons. Alles als Inline-SVG, kein Icon-Font.
  • Schriften self-hosted über @fontsource-variable. Keine Google-Fonts vom CDN, kein Drittanbieter-Tracking durch die Hintertür.

Builds sind unter 30 Sekunden durch, der ganze dist/-Ordner liegt bei ungefähr 2 MB.

Hosting

Hosting läuft auf einem HP T630 Thin Client im Homelab. Debian 13, kein Cloud-VPS, kein Managed-Hosting. Der T630 ist ein lüfterloser Mini-PC, der ursprünglich für Office-Arbeitsplätze gedacht war. Reicht für eine statische Site mehr als locker und braucht ein paar Watt im Idle. Drei Komponenten greifen ineinander:

  1. Cloudflare Tunnel terminiert HTTPS am Cloudflare-Edge und routet den Traffic über einen ausgehenden Tunnel zum Server. Der Server steht vom Internet aus nicht direkt erreichbar im LAN: keine offenen Ports, kein DDoS-Risiko, automatisches TLS, kein Let’s-Encrypt-Theater.
  2. Caddy in Docker als interner Reverse-Proxy. Serviert die statischen Files und setzt Cache-Header. Astros gehashte Assets bekommen max-age=31536000, immutable, HTML deutlich kürzer, damit Updates schnell ankommen.
  3. systemd verwaltet den cloudflared-Service, damit er auch nach Reboots wieder hochkommt.

Die Domain läuft über Cloudflare DNS. Keine monatliche Hosting-Rechnung, keine Hoster-Abhängigkeit, keine Sorge um automatische Vertragsverlängerungen oder Preiserhöhungen.

Deploy ohne CI

GitHub Actions würden den Server im LAN nicht erreichen, also kein klassisches CI/CD. Stattdessen ein einziges Bash-Script ./push, das vier Schritte hintereinander macht:

  1. Build (npm run build)
  2. rsync der dist/-Files auf den Server, mit ssh-Key
  3. git push origin <branch>
  4. curl-Smoke-Test, ob die Live-URL noch 200 zurückgibt

Bei einer Update-Frequenz von ein paar Pushes im Monat ist das weniger Wartung als jeder Auto-Deploy mit Tailscale-Brücke wäre. Wenn die Frequenz mal hochgeht, kann man die Brücke immer noch ergänzen.

Was unterwegs gelernt wurde

  • Default-Configs des Themes rausschmeißen, bevor man deployed. Sitemap und Robots.txt verwenden sonst die Theme-Default-Domain. Sah in den Search-Tools drei Tage lang merkwürdig aus, bis das auffiel.
  • Demo-Inhalte löschen, nicht verstecken. AstroWind hat ein Dutzend Demo-Seiten als Anschauungsmaterial. Wenn die im Build landen, stehen sie in der Sitemap und Google indiziert “/landing/click-here-buy-now”. Die ganzen Verzeichnisse homes/ und landing/ müssen weg, nicht nur aus der Navigation gehängt.
  • Cloudflare Cache-TTL muss explizit auf “Respect Existing Headers” stehen, sonst überschreibt Cloudflare die Cache-Header die Caddy setzt mit eigenen Defaults. Dann hängt der Browser bis zu vier Stunden auf alten Bildern fest.
  • Cloudflare AI-Audit prepended sonst eine Content-Signals-Policy vor die robots.txt mit Disallow-Regeln für AI-Bots. Genau das Gegenteil davon was man will, wenn man in ChatGPT, Claude und Perplexity sichtbar sein will.
  • Lighthouse-Mobile spinnt manchmal und wirft NO_LCP, was die anderen Performance-Metriken in Mitleidenschaft zieht. Ist ein Lighthouse-Bug bei sehr leichten Seiten, kein UX-Problem. Erkennt man, wenn alle anderen Werte (FCP, CLS, Speed Index) trotzdem im grünen Bereich sind.

Stand heute: Lighthouse 100/96/100/92 (Performance/Accessibility/Best Practices/SEO), läuft seit Go-Live ohne Vorfall.