Caddy is a web server that automatically provisions and renews HTTPS certificates. No certbot, no nginx config files, no manual renewal — just works.
Why Caddy?
- Automatic HTTPS — provisions TLS certificates from Let's Encrypt automatically
- Zero config — a 3-line Caddyfile replaces 50 lines of nginx config
- HTTP/3 — supported out of the box
- API-first — configure everything via JSON API at runtime
Quick Start
# Install
brew install caddy # macOS
apt install caddy # Ubuntu
# Serve current directory
caddy file-server --browse
# Reverse proxy
caddy reverse-proxy --to localhost:3000
Caddyfile (The Simplest Config)
# Serve static site with HTTPS
mysite.com {
root * /var/www/mysite
file_server
}
# Reverse proxy
api.mysite.com {
reverse_proxy localhost:3000
}
# SPA with fallback
app.mysite.com {
root * /var/www/app
try_files {path} /index.html
file_server
}
That's it. Caddy automatically gets TLS certs for all three domains.
Reverse Proxy with Load Balancing
myapp.com {
reverse_proxy {
to localhost:3001
to localhost:3002
to localhost:3003
lb_policy round_robin
health_uri /health
health_interval 10s
}
}
Headers, CORS, Compression
api.mysite.com {
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
X-Frame-Options DENY
-Server # Remove server header
}
encode gzip zstd
reverse_proxy localhost:3000
}
Admin API (Runtime Config)
# Get current config
curl localhost:2019/config/
# Add a new site at runtime
curl -X POST localhost:2019/config/apps/http/servers/srv0/routes \
-H 'Content-Type: application/json' \
-d '{
"match": [{"host": ["new.mysite.com"]}],
"handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:4000"}]}]
}'
# Load entire config
curl -X POST localhost:2019/load \
-H 'Content-Type: application/json' \
-d @caddy.json
Rate Limiting
api.mysite.com {
rate_limit {
zone api {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:3000
}
Docker Compose
services:
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
app:
build: .
expose:
- "3000"
volumes:
caddy_data:
caddy_config:
Deploying scraping infrastructure? Check out my Apify actors for managed web scraping, or email spinov001@gmail.com for custom deployment solutions.
Caddy, Nginx, or Traefik — which web server do you use? Share below!
Top comments (0)