Nginx oder Caddy? Eine Architekturentscheidung

Cyber Panda als Psychologe zwischen zwei Servern Die Architekturentscheidung: Welcher Webserver passt zu deinem Projekt?

Einleitung

Du baust einen neuen Service, brauchst einen Reverse Proxy und stehst vor der Qual der Wahl: Nginx oder Caddy? Beide können HTTP/2, TLS termination, Load Balancing und Statics ausliefern. Aber die Art, wie sie das tun, ist unterschiedlich genug, um die Wahl zur Architekturentscheidung zu machen. Ich habe die Entscheidung kürzlich für ein internes Tool treffen müssen und möchte die Kriterien teilen.

Kontext

Es geht um ein kleines bis mittleres Projekt: eine API mit Frontend, das von internen Nutzern und einigen externen Partnern verwendet wird. Traffic ist überschaubar — im Schnitt unter 1.000 Requests pro Minute, mit gelegentlichen Spitzen bei Kunden-Events. Das Team besteht aus zwei Entwicklern, die mit Node.js und Go vertraut sind, aber keine langjährige Sysadmin-Erfahrung haben.

Was auf dem Spiel steht: Einfache Wartung, automatische Zertifikatserneuerung, schnelle Deployments. Non-Goals: High-Performance-Load-Balancing für zehntausendfache Parallelität, komplexe Rewrite-Regelwerke oder nativer Support für proprietäre Protokolle.

Option A: Nginx

Nginx ist der Platzhirsch. Stabil, performant, seit Jahren in Produktion bewährt.

Pros:

  • Extrem geringer Speicherverbrauch, selbst bei tausenden Connections
  • Reifes Ökosystem mit Modulen für fast alles
  • Weit verbreitet — Dokumentation und Stack Overflow sind reichhaltig

Cons:

  • Konfiguration erfolgt über Textdateien mit eigener DSL, die steile Lernkurve hat
  • TLS-Zertifikate musst du selbst verwalten oder externe Tools wie certbot anbinden
  • Kleine Fehler in der Config führen zu 502/504 ohne aussagekräftige Fehlermeldung
# Beispiel: Nginx-Konfiguration für Reverse Proxy
server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Option B: Caddy

Caddy positioniert sich als moderner, entwicklerfreundlicher Webserver mit automatischer HTTPS-Konfiguration.

Pros:

  • Zero-Config HTTPS: Caddy holt und erneuert Zertifikate automatisch via Let’s Encrypt
  • Einfache, menschenlesbare Konfiguration im Caddyfile-Format
  • Weniger Overhead für Standardaufgaben — ideal, wenn du kein Nginx-Experte werden willst

Cons:

  • Weniger ausgereift in Edge-Cases; die Community ist kleiner als bei Nginx
  • Performance ist gut, aber nicht auf dem Niveau von Nginx bei extrem hohem Traffic
  • Einige Nginx-Module haben kein direktes Caddy-Äquivalent
# Beispiel: Caddyfile-Konfiguration für Reverse Proxy
api.example.com {
    reverse_proxy 127.0.0.1:3000
    encode gzip
}

Entscheidung

Ich habe mich für Caddy entschieden.

Die Begründung ist pragmatisch: Das Team soll sich auf die Anwendungslogik konzentrieren, nicht darauf, TLS-Zertifikate manuell zu verlängern oder Nginx-Direktiven zu debuggen. Caddy erledigt HTTPS ohne weitere Toolchain, die Config ist in fünf Minuten verstanden, und Deployments werden einfacher.

Der Trade-off: Für den Fall, dass der Traffic in einem Jahr auf 10.000 Requests pro Minute wächst, müssen wir migrieren. Aber die Wahrscheinlichkeit ist gering, und die Migrationskosten sind überschaubar — Caddy und Nginx lassen sich parallel betreiben, bis der Cutover stattfindet. Ich akzeptiere dieses Risiko zugunsten der aktuellen Entwicklungsgeschwindigkeit.

Implementierung

Der Einstieg ist ein einziger Befehl:

# Installation auf Ubuntu/Debian
sudo apt install -y caddy

Der Caddyfile kommt ins Projektverzeichnis:

# /etc/caddy/Caddyfile oder ./Caddyfile im Projekt
api.example.com {
    reverse_proxy localhost:3000
    encode gzip
}

frontend.example.com {
    root * /var/www/frontend/dist
    file_server
}

Ein caddy reload genügt, und HTTPS steht — ohne certbot, ohne Cronjob für die Erneuerung. Das ist der Unterschied, der für uns zählt.

Fazit

Nginx bleibt die richtige Wahl, wenn du maximale Performance brauchst, bereits Nginx-Erfahrung im Team hast oder komplexe Routing-Regeln abbilden musst. Für Projekte im mittleren Größenbereich, bei denen Einfachheit und schnelle Deployments wichtiger sind als Spitzenperformance, ist Caddy die effizientere Lösung.

Die Metrik, die für uns zählt: Die Zeit vom “Service soll online gehen” bis “HTTPS funktioniert” ging von etwa zwei Stunden auf unter fünf Minuten runter. Das ist kein Messwert, den man leichtfertig ignoriert.

Hat jemand von euch Caddy bereits in größeren Umgebungen betrieben? Ich bin neugierig, wo die praktischen Grenzen liegen.