Caddy is a modern web server that automatically handles HTTPS certificate provisioning and renewal via Let's Encrypt. It requires minimal configuration and is an excellent choice for simple to medium-complexity deployments.
Why Caddy?
- Automatic HTTPS — Obtains and renews Let's Encrypt certificates with zero configuration
- HTTP/2 and HTTP/3 by default
- Simple Caddyfile syntax (much simpler than Nginx)
- Automatic OCSP stapling
- Single binary, no dependencies
Installation
# Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt" | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
# Or download binary
curl -fsSL https://caddyserver.com/api/download | sudo tee /usr/bin/caddy > /dev/null
sudo chmod +x /usr/bin/caddyBasic Caddyfile
# /etc/caddy/Caddyfile
# Static site — automatic HTTPS!
example.com {
root * /var/www/example.com
file_server
}
# Reverse proxy
api.example.com {
reverse_proxy localhost:3000
}
# PHP application
myapp.com {
root * /var/www/myapp/public
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
encode gzip
}
# Multiple domains on one site
example.com, www.example.com {
root * /var/www/example.com
file_server
}Advanced Configuration
# Caddyfile with all features
example.com {
root * /var/www/example.com/public
# Compression
encode gzip zstd
# Logging
log {
output file /var/log/caddy/access.log
format json
}
# Security headers
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Strict-Transport-Security "max-age=63072000"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
# Static file caching
@static {
path *.css *.js *.png *.jpg *.gif *.svg *.woff2
}
header @static Cache-Control "public, max-age=2592000"
# PHP processing
php_fastcgi unix//run/php/php8.3-fpm.sock
# File server (for static files)
file_server
}Caddy as a Reverse Proxy with Load Balancing
api.example.com {
reverse_proxy {
to localhost:3001
to localhost:3002
to localhost:3003
lb_policy least_conn
health_uri /health
health_interval 10s
}
}
# WebSocket support (automatic)
ws.example.com {
reverse_proxy localhost:8080
}Managing Caddy
# Validate configuration
caddy validate --config /etc/caddy/Caddyfile
# Reload without downtime
sudo systemctl reload caddy
# Format Caddyfile
caddy fmt --overwrite /etc/caddy/Caddyfile
# View certificates
caddy list-modules
sudo ls /var/lib/caddy/.local/share/caddy/certificates/Caddy vs Nginx
| Feature | Caddy | Nginx |
|---|---|---|
| Auto HTTPS | Built-in | Requires Certbot |
| Configuration | Very simple | More complex |
| Performance | Very good | Excellent |
| HTTP/3 | Built-in | Requires build flag |
| Ecosystem | Growing | Mature, extensive |
| Best for | Simple-medium sites | Complex deployments |