3 Min. Lesezeit
Ein Server ist leicht zu durchschauen
Ein einzelner VPS, Caddy und Docker Compose
Teil neun des Boring Stack. Die App ist ein einzelnes Go-Binary mit ihren Daten in einer SQLite-Datei. Wo soll das laufen?
Die modischen Antworten sind eine verwaltete Plattform, Serverless-Funktionen oder ein Kubernetes-Cluster. Ich habe Kubernetes auf Bare Metal betrieben und auf dieser Seite darüber geschrieben. Für meine eigenen Apps miete ich einen virtuellen Server.
Das Setup
- Ein VPS bei Hetzner, mit mehr CPU und Arbeitsspeicher, als meine Apps brauchen.
- Caddy davor. Caddy ist ein Webserver, der TLS-Zertifikate selbst holt und erneuert. Er leitet jede Domain an die richtige App weiter. Statische Websites sind Ordner, die Caddy direkt ausliefert.
- Docker Compose für die Apps. Jede App ist ein Container mit zwei Ordnern vom Host: einer für die SQLite-Datenbank, einer für hochgeladene und erzeugte Dateien. Der ganze Zustand liegt in diesen zwei Ordnern.
- Cloudflare vor allem, für DNS und Caching.
Wie ein Deploy abläuft
Ein Push auf master startet die Pipeline auf einem selbst gehosteten GitHub-Runner. Sie lintet den Code, baut ein Docker-Image und versieht es mit dem Commit-Hash. Dann kopiert sie eine Compose-Datei mit genau diesem Tag auf den Server und führt docker compose pull && docker compose up -d aus.
Der Image-Tag steht als Klartext in der Datei, nicht als Variable. Ein späterer Neustart auf dem Server nimmt immer genau das Image, das deployt wurde, nicht das, worauf latest gerade zeigt.
Statische Seiten überspringen all das. Sie werden gebaut, und die geänderten Dateien kommen per rsync auf den Server.
Warum ein Server
- Ich kann alles verstehen. Eine Maschine, eine Webserver-Konfiguration, eine Compose-Datei pro App. Wenn etwas nicht stimmt, gibt es wenige Orte zum Nachschauen.
- Es ist günstig. Ein fester Monatspreis für alles, ohne Rechnung, die mit Traffic oder Anfragen wächst.
- Backups sind einfach. Alles, was zählt, liegt in wenigen Ordnern. Sie woandershin zu kopieren ist das Backup.
- Es ist schnell. Keine Kaltstarts, kein Netzwerk zwischen App und Datenbank.
Die Einstellung, die beisst
Eine Lektion, mehr als einmal gelernt: Mit Cloudflare vor Caddy braucht jede neue Domain den SSL/TLS-Modus Full (strict). Standard für eine neue Zone ist «Flexible», bei dem Cloudflare mit dem Server über unverschlüsseltes HTTP spricht. Caddy antwortet auf HTTP mit einer Weiterleitung auf HTTPS, Cloudflare gibt sie an den Browser weiter, und der Browser fragt erneut. Die Seite lädt nie. Das Symptom ist ein HTTP 308, das genau auf die URL zeigt, die man aufgerufen hat.
Das steht jetzt als Zeile in meiner Projektvorlage, damit die nächste Seite mit der richtigen Einstellung startet.
Was es kostet
- Ein Server ist ein Single Point of Failure. Fällt er aus, fällt alles darauf aus. Für meine Apps ist ein kurzer Ausfall in Ordnung. Für ein Spitalsystem nicht.
- Ich bin das Betriebsteam. Updates, Firewall, Speicherplatz und Überwachung liegen bei mir. Ein kleines Setup hält diese Arbeit klein.
- Skalieren geht nach oben, nicht in die Breite. Braucht eine App mehr, miete ich einen grösseren Server. Das reicht überraschend weit.
Wann ich anders entscheiden würde
Wenn ein Ausfall echtes Geld kostet oder Menschen gefährdet, will ich Redundanz und damit eine komplexere Plattform. Im Beruf ist das oft die richtige Entscheidung. Für die Apps, die ich selbst baue, schlägt ein Server, den ich ganz verstehe, eine Plattform, die ich nur teilweise verstehe.
Als Nächstes und zum Schluss: die Websites.