---
title: "Caddy Reverse Proxy Config"
description: "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."
type: reference
domain: server-configs
tags: [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

```bash
# 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
```
