Subdomain Registry und Caddy¶
Diese Seite beschreibt das Routing-Konzept für HTTP/S-Dienste. Sie erklärt die Abgrenzung zwischen der zentralen Subdomain Registry, Caddy, CaddyManager und den bewusst manuell gepflegten Mail-Routen.
Grundprinzip¶
Caddy ist der öffentliche HTTP/S-Einstiegspunkt des Servers. Für normale Webdienste wird Caddy nicht direkt pro Dienst von Hand erweitert, sondern aus der zentralen Registry generiert:
/opt/selfhost/registry/routes.json
Der Generator:
/opt/selfhost/tools/selfhost-routes
liest diese Registry und erzeugt daraus unter anderem:
| Artefakt | Pfad | Zweck |
|---|---|---|
| Caddy-Snippet | /opt/selfhost/generated/caddy/routes.caddy |
aktive Nicht-Mail-Routen für Caddy |
| Homepage-Liste | /opt/selfhost/generated/homepage/services.yaml |
Einträge für das Dashboard |
| Registry-Doku | /opt/selfhost/generated/docs/subdomains.md |
generierte technische Übersicht |
| Portliste | /opt/selfhost/generated/docs/ports.csv |
generierte Portübersicht |
| DNS-Hinweise | /opt/selfhost/generated/docs/dns-records.txt |
generierte DNS-Liste |
| Web-Übersicht | /opt/selfhost/generated/routes/index.html |
lesende Tabellenansicht der Registry |
Das Haupt-Caddyfile importiert das generierte Snippet:
import /opt/selfhost/generated/caddy/routes.caddy
Warum eine Registry?¶
Die Registry verhindert, dass Subdomains an mehreren Stellen mit widersprüchlichen Informationen gepflegt werden. Sie bündelt:
- Hostname oder Subdomain
- Zieltyp: Reverse Proxy, statische Seite oder Redirect
- Upstream und Port
- Kategorie für Dashboard und Dokumentation
- Beschreibung
- Hinweise, ob ein Hostname auch in der Zielanwendung konfiguriert werden muss
- Tailnet-Schutzregeln für ausgewählte Oberflächen
Dadurch kann ein neuer normaler Webdienst mit einem kontrollierten Ablauf veröffentlicht werden.
Route-Typen¶
| Typ | Bedeutung | Beispiel |
|---|---|---|
reverse_proxy |
Caddy leitet an einen lokalen Dienst weiter | Open WebUI auf 127.0.0.1:3020 |
static |
Caddy liefert Dateien aus einem lokalen Ordner aus | Dokumentation aus /opt/selfhost/site |
redirect |
Caddy leitet auf einen anderen Host/Pfad um | Provider-Hostname auf VPS-Landing |
Zugriffsschutz nach Authentik¶
Authentik ist aus der aktiven Infrastruktur entfernt. Die Registry verwendet deshalb keinen produktiven Forward-Auth-Mechanismus mehr.
Aktuelle Zugriffsmuster:
| Muster | Bedeutung |
|---|---|
| eigene Dienst-Auth | Der Dienst hat Login, API-Keys oder eigene Sessionverwaltung |
| Tailnet-only | Caddy erlaubt den eigentlichen Dienst nur für Tailscale-Quell-IP-Bereiche |
| öffentlich | bewusst öffentlich erreichbar, typischerweise Website oder öffentliche Mail-bezogene Endpunkte |
Für Tailnet-only-Routen wird außerhalb des Tailnets die vorhandene OpenClaw-Hinweisseite ausgeliefert:
/opt/selfhost/generated/openclaw-error/
Dabei werden aktuell die Tailscale-IP-Bereiche 100.64.0.0/10 und fd7a:115c:a1e0::/48 verwendet.
Wichtig: Die Tailnet-Erkennung basiert auf der Quell-IP, die bei Caddy ankommt. Ein Client ist nur dann als Tailnet-Client erkennbar, wenn er den Server auch über die Tailscale-Adresse erreicht. Wenn ein Browser trotz aktivem Tailscale über den öffentlichen DNS-A-Record 62.141.32.194 verbindet, sieht Caddy nur die normale öffentliche Client-IP und liefert bewusst die Fallback-Seite aus. Für komfortable Nutzung mit normalen Hostnames sollten Tailnet-only-Hostnames zusätzlich einen DNS-Eintrag auf die Tailscale-Adresse des VPS haben, idealerweise als AAAA auf fd7a:115c:a1e0::1c34:af3e. Dann verwenden Tailnet-Clients die Tailscale-Verbindung, während externe Clients weiterhin über den öffentlichen A-Record die harmlose Fallback-Seite erreichen können.
Beispiel einer Tailnet-only Static Route¶
Die Serverdokumentation wird als statische MkDocs-Seite veröffentlicht und per Tailnet geschützt:
{
"id": "serverdocs",
"enabled": true,
"title": "Serverdokumentation",
"hostname": "serverdocs.marcosudau.com",
"type": "static",
"root": "/opt/selfhost/site",
"auth": "none",
"category": "Administration",
"dashboard": true,
"caddy": {
"tailnetOnly": {
"fallbackRoot": "/opt/selfhost/generated/openclaw-error",
"remoteIpRanges": ["100.64.0.0/10", "fd7a:115c:a1e0::/48"]
}
}
}
Standardablauf bei Änderungen¶
Nach einer Änderung an /opt/selfhost/registry/routes.json:
sudo /opt/selfhost/tools/selfhost-routes validate
sudo /opt/selfhost/tools/selfhost-routes generate --apply-homepage
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Wenn die Dokumentation betroffen ist, zusätzlich:
cd /opt/selfhost
/opt/selfhost/tools/mkdocs-venv/bin/mkdocs build --strict
Mail-Routen sind bewusst ausgenommen¶
Mail-nahe Routen bleiben aus der Registry ausgeschlossen und werden direkt in /etc/caddy/Caddyfile gepflegt. Das betrifft unter anderem:
mail.marcosudau.comautoconfig.marcosudau.comautodiscover.marcosudau.commta-sts.marcosudau.comstalwart.marcosudau.comadminmail.marcosudau.commailadmin.marcosudau.combulwark.marcosudau.comwebmail.marcosudau.com
Der Grund ist, dass Mail-Routen neben normalem Reverse Proxy zusätzliche Besonderheiten haben: Autoconfig/Autodiscover, CORS für Webmail, Admin-Redirects und das Zusammenspiel mit Stalwart. Diese Logik soll nicht in den allgemeinen Generator gezwungen werden.
Abgrenzung zu CaddyManager¶
CaddyManager ist eine Anwendung, die Caddy-Konfiguration bzw. Caddy-API-Zugriff visualisieren oder verwalten kann. Das Routing-Konzept bleibt davon unabhängig.
Wichtige Abgrenzung:
- Die Registry ist die verbindliche Quelle für normale Nicht-Mail-Routen.
- Der Generator schreibt das Caddy-Snippet und die Dashboard-Übersichten.
- CaddyManager ist ein Dienst und wird auf seiner Dienstseite dokumentiert.
- Änderungen an Registry-Routen sollen nicht heimlich nur in CaddyManager oder direkt im generierten Snippet erfolgen.
Wenn CaddyManager für Kontrolle oder Diagnose verwendet wird, muss trotzdem geprüft werden, ob die dauerhafte Quelle der Änderung routes.json oder, bei Mail, /etc/caddy/Caddyfile ist.
Hostname-Änderungen¶
Einige Routen haben hostnameChangeRequiresServiceConfig: true. Das bedeutet nicht, dass der Hostname unveränderlich ist. Es bedeutet: Eine Änderung in Caddy/Registry reicht nicht aus.
Beispiele:
- Hermes API: externe Clients oder OpenWebUI-Konfiguration können den Hostnamen verwenden.
- Open WebUI: Base-URLs, Sessions oder Backend-Konfigurationen können betroffen sein.
- LiteLLM: API-Clients und UI-Redirects können den Hostnamen kennen.
- CaddyManager: CORS-Konfiguration hängt am Hostnamen.
Solche Routen dürfen geändert werden, aber nur zusammen mit den betroffenen Dienstkonfigurationen.