What Is Caddy?
Caddy is a modern, open-source web server and reverse proxy written in Go. Its killer feature: automatic HTTPS with Let’s Encrypt. Unlike Nginx or Apache where you manually configure SSL certificates, Caddy obtains and renews them automatically.
Other Caddy features:
- HTTP/2 and HTTP/3 support out of the box
- Simple configuration with a human-readable Caddyfile
- Built-in metrics and health checks
- Plugin ecosystem for caching, authentication, and more
Caddy is ideal for:
- Developers who want HTTPS without certificate management
- Teams deploying microservices or containerized apps
- Anyone tired of Nginx/Apache configuration complexity
What You Will Need
For this guide, you’ll need:
- A VPS with Ubuntu 22.04 or 24.04 (we recommend a Cloud VPS from Canadian Web Hosting)
- A domain name pointing to your server’s IP
- Root or sudo access
- Ports 80 and 443 open in your firewall
Our Cloud VPS plans include Canadian data centres, 24/7 support, and full root access. Caddy pairs well with other modern tools—for a comparison of web servers behind it, see our Apache vs Nginx comparison. Not comfortable managing servers? Add Managed Support—our team will handle setup and ongoing maintenance.
Step 1: Install Caddy
Caddy provides official repositories for easy installation and updates.
Ubuntu/Debian
sudo apt update
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
Verify Installation
caddy version
You should see something like:
v2.8.4 h1:2hwYqi7wk2hgY3p3pR8nqPoLb6yXh+Z7pjE2k2YVpBQ=
Step 2: Basic Caddyfile Configuration
Caddy’s configuration lives in /etc/caddy/Caddyfile. Let’s create a simple configuration:
sudo nano /etc/caddy/Caddyfile
Add:
your-domain.com {
root * /var/www/html
file_server
}
This tells Caddy:
- Serve
your-domain.com - Use
/var/www/htmlas the document root - Enable the file_server directive (serves static files)
Replace your-domain.com with your actual domain.
Step 3: Start Caddy and Enable Auto-HTTPS
Caddy runs as a systemd service. Start it:
sudo systemctl start caddy
sudo systemctl enable caddy
Check status:
sudo systemctl status caddy
Now visit http://your-domain.com. Caddy will:
- Detect the request over HTTP
- Obtain a Let’s Encrypt certificate automatically
- Redirect you to HTTPS
- Serve your site with a valid SSL certificate
This happens automatically on first visit. No manual certificate commands needed.
Step 4: Verify HTTPS Works
Visit https://your-domain.com. You should see a padlock in your browser’s address bar.
Check the certificate details:
openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -subject -dates
You’ll see the certificate issuer (Let’s Encrypt) and expiry date (~90 days from now).
Step 5: Reverse Proxy Configuration
Caddy’s real power is as a reverse proxy. Let’s proxy to a local application running on port 3000:
your-domain.com {
reverse_proxy localhost:3000
}
Or with multiple backends (load balancing):
your-domain.com {
reverse_proxy localhost:3000 localhost:3001 {
lb_policy round_robin
}
}
Caddy handles:
- SSL termination (HTTPS at the edge, HTTP to backend)
- Load balancing
- Health checks (with
health_urioption) - WebSocket upgrades automatically
Step 6: Advanced Configuration Examples
Multiple Sites (Virtual Hosts)
site1.com {
root * /var/www/site1
file_server
}
site2.com {
root * /var/www/site2
file_server
}
API Gateway Pattern
api.your-domain.com {
route /users/* {
reverse_proxy localhost:4001
}
route /products/* {
reverse_proxy localhost:4002
}
route /orders/* {
reverse_proxy localhost:4003
}
}
Static Site with SPA Routing
app.your-domain.com {
root * /var/www/spa
file_server {
try_files {path} /index.html
}
}
The try_files directive serves index.html for any path that doesn’t match a static file—essential for single-page applications.
Step 7: Security Hardening
1. Restrict Caddy User Permissions
Caddy runs as the caddy user. Limit its capabilities:
sudo systemctl edit caddy
Add:
[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/etc/ssl/caddy /var/lib/caddy
2. Configure Firewall
Allow only necessary ports:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
3. Rate Limiting
Prevent abuse:
your-domain.com {
rate_limit {
zone dynamic {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:3000
}
4. Security Headers
Caddy adds sensible defaults. Add extra headers:
your-domain.com {
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy strict-origin-when-cross-origin
}
reverse_proxy localhost:3000
}
Step 8: Monitoring and Logging
Access Logs
Caddy logs to journald by default:
sudo journalctl -u caddy --since "1 hour ago"
Metrics Endpoint
Enable the metrics plugin in Caddyfile:
:2019 {
metrics
}
Then query metrics at http://localhost:2019/metrics (Prometheus format).
Health Checks
Add a health endpoint:
your-domain.com {
reverse_proxy localhost:3000 {
health_uri /health
health_interval 30s
}
}
Step 9: Troubleshooting Common Issues
Issue: Caddy Won’t Start
Check configuration syntax:
caddy validate --config /etc/caddy/Caddyfile
Check for port conflicts:
sudo ss -tulpn | grep :80
sudo ss -tulpn | grep :443
Issue: Let’s Encrypt Certificate Not Issuing
Common causes:
- Domain doesn’t resolve to server IP
- Port 80 blocked by firewall
- Rate limit exceeded (too many certificate requests)
Test domain resolution:
dig your-domain.com +short
Test port 80 accessibility:
curl -I http://your-domain.com
Issue: Reverse Proxy Not Working
Check backend is running:
curl -I http://localhost:3000
Enable debug logging in Caddy:
sudo systemctl edit caddy
Add:
[Service]
Environment=CADDY_LOG_LEVEL=DEBUG
Then restart and check logs:
sudo systemctl restart caddy
sudo journalctl -u caddy -f
Step 10: Production Deployment Checklist
- ? Domain configured with A/AAAA records pointing to server
- ? Firewall configured (ports 80/443 open)
- ? Caddy installed from official repository
- ? Caddyfile validated with
caddy validate - ? Systemd service running and enabled
- ? HTTPS working (padlock in browser)
- ? Backend services accessible through reverse proxy
- ? Monitoring configured (logs, metrics, health checks)
- ? Backups configured for Caddyfile and certificates
Conclusion
Caddy eliminates the SSL certificate management burden that comes with Nginx or Apache. With automatic HTTPS, simple configuration, and built-in reverse proxy capabilities, it’s an excellent choice for modern web applications.
Key advantages for Canadian businesses:
- Data sovereignty: Run Caddy on Canadian Web Hosting VPS in Vancouver or Toronto data centres
- Compliance: Automatic HTTPS helps meet security best practices
- Cost savings: No need for paid SSL certificates or complex configuration
Ready to deploy Caddy? Start with a Cloud VPS from Canadian Web Hosting. Need help with setup? Our Managed Support team can configure Caddy, monitor certificates, and handle ongoing maintenance.
Questions about Caddy or reverse proxy configuration? Contact our support team—we’re here 24/7.
Be First to Comment