{"skill":{"slug":"caddy","displayName":"Caddy","summary":"Configure Caddy as a reverse proxy with automatic HTTPS and simple Caddyfile syntax.","description":"---\nname: Caddy\ndescription: Configure Caddy as a reverse proxy with automatic HTTPS and simple Caddyfile syntax.\nmetadata: {\"clawdbot\":{\"emoji\":\"🔒\",\"requires\":{\"bins\":[\"caddy\"]},\"os\":[\"linux\",\"darwin\",\"win32\"]}}\n---\n\n# Caddy Configuration Rules\n\n## Automatic HTTPS\n- Caddy provisions SSL certificates automatically — don't manually configure Let's Encrypt unless you have specific needs\n- Domain must resolve to the server publicly for HTTP challenge — use DNS challenge for internal/wildcard certs\n- Ports 80 and 443 must be free — Caddy needs both even for HTTPS-only (80 handles ACME challenges and redirects)\n- Let's Encrypt has rate limits — use staging CA during testing to avoid hitting production limits\n\n## Caddyfile Syntax\n- Indentation is significant — blocks are defined by indentation, not braces in shorthand\n- Site blocks need a space before the opening brace: `example.com {` not `example.com{`\n- Use `caddy fmt --overwrite` to fix formatting — catches most syntax issues\n- Validate before applying: `caddy validate --config /etc/caddy/Caddyfile`\n\n## Reverse Proxy\n- Caddy adds `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host` automatically — don't add them manually\n- WebSocket works out of the box — no special configuration needed\n- Load balancing is automatic with multiple backends — default is random, use `lb_policy` to change\n- Passive health checks remove failed backends automatically\n\n## Docker Networking\n- Use container names as hostnames: `reverse_proxy container_name:3000`\n- Caddy and backends must share a Docker network — default bridge doesn't support DNS resolution\n- For Docker Compose, service names work as hostnames when on the same network\n\n## Configuration Management\n- Use `caddy reload` not restart — reload applies changes without dropping connections\n- Config changes are atomic — if new config fails validation, old config stays active\n- Test without applying: `caddy adapt --config Caddyfile` shows parsed JSON output\n\n## Certificate Storage\n- Certificates stored in `~/.local/share/caddy` by default — preserve this across reinstalls\n- For Docker, mount volumes for `/data` and `/config` — losing these means re-requesting all certificates\n- Multiple Caddy instances need shared storage or will fight over certificates\n\n## Debugging\n- Enable debug logging: add `debug` as first line in global options block\n- Check certificate status in `/data/caddy/certificates/` directory\n- Common issue: DNS not pointing to server yet — certificates fail silently until domain resolves\n\n## Security Headers\n- Caddy doesn't add security headers by default — add X-Frame-Options, X-Content-Type-Options explicitly\n- HSTS is automatic when serving HTTPS — no manual configuration needed\n\n## Performance\n- Handles thousands of concurrent connections without tuning\n- HTTP/3 available with `servers { protocols h1 h2 h3 }`\n- Compression automatic for text content\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":1396,"installsAllTime":8,"installsCurrent":8,"stars":2,"versions":1},"createdAt":1770741140191,"updatedAt":1778486991803},"latestVersion":{"version":"1.0.0","createdAt":1770741140191,"changelog":"Initial release","license":null},"metadata":{"setup":[],"os":["linux","darwin","win32"],"systems":null},"owner":{"handle":"ivangdavila","userId":"s178jdk12x4qj3gs2se3etxf3h83h7ft","displayName":"Iván","image":"https://avatars.githubusercontent.com/u/81719670?v=4"},"moderation":null}