claude-home/server-configs/caddy-migration/README.md
Cal Corum 4b7eca8a46
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: add YAML frontmatter to all 151 markdown files
Adds title, description, type, domain, and tags frontmatter to every
doc for improved KB semantic search. The description field is prepended
to every search chunk, and domain/type/tags enable filtered queries.

Type values: context, guide, runbook, reference, troubleshooting
Domain values match directory structure (networking, docker, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:00:44 -05:00

4.0 KiB

title description type domain tags
Caddy Reverse Proxy Config Caddy configuration reference replacing Nginx Proxy Manager on 10.10.0.16. Documents all 22 proxied services (public and internal-only), DNS-01 wildcard certs via Cloudflare, feature comparison with NPM, and management commands. reference server-configs
caddy
reverse-proxy
cloudflare
dns-01
wildcard-cert
docker
caddyfile

Caddy Reverse Proxy - NPM Replacement

Caddy configuration to replace Nginx Proxy Manager (NPM) on 10.10.0.16 for the manticorum.com homelab.

Why Caddy

  • Single config file instead of a web UI + SQLite database
  • Automatic HTTPS with built-in Let's Encrypt and zero-downtime renewal
  • Wildcard cert via DNS-01 replaces 22 individual HTTP-01 certs
  • HTTP/3 (QUIC) support out of the box
  • WebSocket proxying works automatically without per-host toggles
  • Git-friendly - the entire proxy config is a single version-controlled file

Architecture

Clients -> Pi-hole DNS (10.10.0.16) -> Caddy (10.10.0.16:443) -> Backend services

Caddy replaces NPM in the same position. Pi-hole sync script updated to parse the Caddyfile instead of NPM's SQLite database.

Files

File Purpose
Caddyfile Main reverse proxy configuration (all 22 proxy hosts)
docker-compose.yml Container deployment
Dockerfile Custom Caddy build with Cloudflare DNS plugin
.env.example Required environment variables
scripts/caddy-pihole-sync.sh Pi-hole DNS sync (replaces npm-pihole-sync.sh)

Proxied Services

Public (no IP restriction)

Domain Backend Notes
sbadev.manticorum.com 10.10.0.33:801 CORS header added
sbanews.manticorum.com 10.10.0.88:2368 Ghost blog
pddev.manticorum.com 10.10.0.42:813 Paper Dynasty dev
foundry.manticorum.com 10.10.0.223:30000 Foundry VTT
pds.manticorum.com 10.10.0.42:810 PD staging
n8n.manticorum.com 10.10.0.210:5678 300s timeouts
gameplay-demo.manticorum.com 10.0.0.206:3000
gameplay-api-demo.manticorum.com 10.0.0.206:8000
memos.manticorum.com 10.10.0.222:5230
notes.manticorum.com 10.10.0.222:8000 NoteDiscovery
vagabond.manticorum.com 10.10.0.223:30000 Foundry VTT alt
pocket.manticorum.com 10.0.0.233:80
git.manticorum.com 10.10.0.225:3000 Gitea
omnitools.manticorum.com 10.10.0.210:8080
termix.manticorum.com 10.10.0.210:8180
status.manticorum.com 10.10.0.227:3001 Uptime Kuma
jellyfin.manticorum.com 10.10.0.226:8096

Internal Only (10.0.0.0/23, 10.10.0.0/24, home IP)

Domain Backend
radarr.manticorum.com 10.10.0.221:7878
sonarr.manticorum.com 10.10.0.221:8989
jellyseer.manticorum.com 10.10.0.221:5055
openclaw.manticorum.com 10.10.0.224:18789

What Changed from NPM

Feature NPM Caddy
SSL certs 22 individual LE certs (HTTP-01) 1 wildcard cert (DNS-01 via Cloudflare)
WebSocket Per-host toggle Automatic
HTTP/2 Per-host toggle Always on
HTTP/3 Not supported Built-in
HSTS Per-host toggle Automatic with HTTPS
Config format SQLite DB + web UI Caddyfile (text)
Admin panel Port 81 web UI SSH + text editor / Caddy API on :2019
"Block exploits" Built-in toggle Rely on Cloudflare WAF
Real IP from CF Manual nginx.conf edit trusted_proxies in global block
Pi-hole sync Scrapes SQLite DB Parses Caddyfile

Management

# SSH to host
ssh pihole

# Validate config
docker exec caddy caddy validate --config /etc/caddy/Caddyfile

# Reload after editing (zero downtime)
docker exec caddy caddy reload --config /etc/caddy/Caddyfile

# View logs
docker logs caddy -f

# Check cert status
docker exec caddy caddy list-modules  # verify cloudflare module loaded
curl -s localhost:2019/config/ | jq .  # full runtime config via API

# Rebuild container (after Dockerfile changes)
cd ~/caddy && docker compose up -d --build