caddy-multisite
The reverse-proxy and routing pattern that fronts the Reptile Industries deployment, distilled into a configurable Caddy template anyone can lift and adapt.
Origin
Every self-hosted operator eventually ends up with a Caddyfile that does the same handful of things: several subdomains, some gated areas behind an auth backend, a couple of dynamic apps reverse-proxied with WebSocket support, and a friendly login redirect rather than a bare 401.
caddy-multisite is that Caddyfile, with the deployment-specific identifiers stripped and the structure that actually does the work preserved. It is the assembled production shape, not a single-directive demonstration.
What is in it
Multi-subdomain static hosting
One Caddyfile, several site roots under /srv/*, each driven by {$SITE_DOMAIN} environment substitution. Reusable snippets — (static_site) and (security_headers) — collapse the per-site block to two lines.
forward_auth gating
Any path can be put behind a single /verify endpoint on your auth service. Two-hundred is allow, four-oh-one is deny, and an X-Required-Tier hint is forwarded so the backend can scope its check. Identity headers come back via copy_headers.
401 to login redirect
A handle_errors block catches the backend's 401 and turns it into /login/?next=<original-url>. The user lands on a sign-in page that knows where to send them after authentication completes.
Reverse proxy with WebSockets
Generic block for fronting a dynamic backend. Connection upgrades are handled by Caddy automatically; only X-Real-IP is set explicitly — the rest are forwarded by default.
The auth pattern
The whole gated-area shape distilled into one block. Your backend supplies a single GET /verify endpoint; the redirect, header forwarding, and error handling are Caddy's responsibility.
Why it is public
Caddy's documentation covers each of these directives individually. What is missing is the assembled production shape — and the production shape is what spares you re-deriving it on every box you set up.
The template ships with placeholder static sites so it boots out of the box, and a documented /verify contract you can satisfy with Authelia, tinyauth, oauth2-proxy, or a thirty-line service of your own.
caddy-multisite on GitHub
Caddyfile, compose, the documented auth contract, and an example layout.