Caddy is a modern web server that eliminates the most tedious parts of Nginx and Apache administration: SSL certificate management. Caddy automatically obtains and renews Let’s Encrypt certificates for every domain it serves — no Certbot, no cron jobs, no manual renewal. For developers who want a production-ready web server on a Hong Kong VPS without Nginx’s configuration complexity, Caddy is a compelling alternative.
Caddy vs Nginx: Key Differences
| Feature | Caddy | Nginx |
|---|---|---|
| Automatic HTTPS | ✅ Built-in, zero config | ❌ Requires Certbot setup |
| Configuration syntax | Simple Caddyfile | Complex nginx.conf |
| Performance | Excellent (Go-based) | Excellent (C-based) |
| HTTP/3 (QUIC) | ✅ Built-in | Requires additional config |
| Learning curve | Low | Moderate to high |
| Plugin ecosystem | Growing | Mature and extensive |
| Memory usage (idle) | ~30–50 MB | ~10–20 MB |
Step 1: Install Caddy
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install caddy
caddy version
systemctl status caddyStep 2: Basic Caddyfile Configuration
nano /etc/caddy/Caddyfile# Caddy automatically handles HTTPS for all domains listed
# No certificate configuration needed — Caddy obtains Let's Encrypt certs automatically
# Static website
yourdomain.com {
root * /var/www/yourdomain.com
file_server
encode gzip zstd
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy no-referrer-when-downgrade
}
}
# Reverse proxy to Node.js application
api.yourdomain.com {
reverse_proxy 127.0.0.1:3000 {
health_uri /health
health_interval 30s
lb_policy round_robin
}
# Rate limiting
rate_limit {
zone api {
key {remote_host}
events 100
window 1m
}
}
}
# Reverse proxy with load balancing to multiple backends
app.yourdomain.com {
reverse_proxy 127.0.0.1:3000 127.0.0.1:3001 127.0.0.1:3002 {
lb_policy least_conn
health_uri /health
}
}
# PHP application (with PHP-FPM)
php.yourdomain.com {
root * /var/www/phpapp
php_fastcgi unix//run/php/php8.2-fpm.sock
file_server
encode gzip
}
# Redirect www to non-www
www.yourdomain.com {
redir https://yourdomain.com{uri} permanent
}
# Basic auth protected admin area
admin.yourdomain.com {
basicauth {
# Generate with: caddy hash-password
admin $2a$14$HASH_HERE
}
reverse_proxy 127.0.0.1:8080
}
# Wildcard subdomain routing (requires DNS challenge for SSL)
*.yourdomain.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
@tenant host {labels.1}.yourdomain.com
reverse_proxy @tenant 127.0.0.1:3000
}# Validate configuration
caddy validate --config /etc/caddy/Caddyfile
# Reload Caddy with new config (zero downtime)
systemctl reload caddyStep 3: Environment Variables and Secrets
nano /etc/caddy/.envCLOUDFLARE_API_TOKEN=your_cloudflare_api_tokennano /etc/systemd/system/caddy.service.d/override.conf[Service]
EnvironmentFile=/etc/caddy/.envsystemctl daemon-reload
systemctl restart caddyStep 4: Caddy API for Dynamic Configuration
Caddy exposes an admin API for runtime configuration changes without restart:
# Add a new reverse proxy route without restarting Caddy
curl -X POST "http://localhost:2019/config/apps/http/servers/srv0/routes" \
-H "Content-Type: application/json" \
-d '{
"@id": "new-route",
"match": [{"host": ["newservice.yourdomain.com"]}],
"handle": [{
"handler": "reverse_proxy",
"upstreams": [{"dial": "127.0.0.1:4000"}]
}]
}'
# View current configuration
curl http://localhost:2019/config/
# Remove a route
curl -X DELETE "http://localhost:2019/id/new-route"This API makes Caddy excellent for dynamically provisioned multi-tenant applications — add new customer subdomains via API call without Caddy restart or file editing.
Step 5: Caddy for Plausible, n8n, and Other Self-Hosted Services
# Combined Caddyfile for multiple self-hosted services on one Hong Kong VPS
analytics.yourdomain.com {
reverse_proxy 127.0.0.1:8000 # Plausible Analytics
}
automation.yourdomain.com {
reverse_proxy 127.0.0.1:5678 # n8n
}
cloud.yourdomain.com {
reverse_proxy 127.0.0.1:8080 # Nextcloud
# Increase header size for Nextcloud
header_up Host {host}
request_body {
max_size 10GB
}
}
ai.yourdomain.com {
reverse_proxy 127.0.0.1:11434 # Ollama LLM API
basicauth {
api_user $2a$14$HASH_HERE
}
}Conclusion
Caddy on a Hong Kong VPS eliminates SSL certificate management entirely — every domain you add to the Caddyfile gets automatic HTTPS with no additional configuration. For developers who find Nginx’s SSL configuration overhead a friction point, Caddy’s zero-config HTTPS combined with CN2 GIA routing makes for an excellent Asia-Pacific web server setup.
Deploy Caddy on Server.HK’s Hong Kong VPS plans — full root access and KVM virtualisation support Caddy’s systemd service and automatic certificate management without any restrictions.
Frequently Asked Questions
Does Caddy work on Hong Kong VPS without a domain name?
Caddy’s automatic HTTPS requires a domain name for Let’s Encrypt certificate issuance. Without a domain, Caddy can still serve HTTP or generate self-signed certificates. For production use with HTTPS, point a domain’s DNS A record to your VPS IP before configuring Caddy.
Is Caddy faster or slower than Nginx?
Caddy and Nginx have comparable throughput for typical web serving and reverse proxy workloads. Nginx has a slight edge in raw performance for very high concurrency (100,000+ simultaneous connections), while Caddy uses slightly more memory at idle. For the vast majority of VPS workloads, the performance difference is negligible — choose based on configuration simplicity (Caddy) vs ecosystem maturity (Nginx).
Can Caddy replace Nginx for all use cases on a Hong Kong VPS?
Caddy handles the most common use cases — static file serving, reverse proxying, PHP-FPM, and automatic HTTPS — with less configuration than Nginx. Nginx’s broader ecosystem (more third-party modules, more production documentation) makes it preferable for complex configurations like custom load balancing algorithms, advanced caching, or specialised streaming setups. For straightforward web serving and reverse proxy needs, Caddy is an excellent Nginx replacement.