Set up Caddy for automatic HTTPS on a VPS
Caddy is a modern web server that gets you free HTTPS with zero configuration. Learn to install it and serve a site or reverse-proxy an app with automatic SSL.
Caddy is a modern web server whose headline feature is automatic HTTPS. Point it at a domain and it obtains, installs and renews a Let's Encrypt certificate for you โ no Certbot, no manual config. For many projects it's the fastest path from VPS to secure website.
Why Caddy
- HTTPS by default โ TLS certificates are fetched and renewed automatically.
- Tiny config โ the
Caddyfileis often just a few lines. - Great reverse proxy โ perfect for putting HTTPS in front of a Node.js, Python or Go app.
- Single binary โ no sprawling dependency tree.
Step 1: Install Caddy
On Ubuntu or Debian, add the official repository and install:
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 -y
Caddy installs as a systemd service and starts immediately. Confirm it's running:
systemctl status caddy
Step 2: Open the firewall
Caddy needs ports 80 and 443 โ 80 is used for the certificate challenge and redirects:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Step 3: Point your domain at the server
Create an A record for your domain pointing at the VPS IP. Caddy can only get a certificate once the domain resolves to the server.
Step 4: Serve a static site
Caddy is configured by /etc/caddy/Caddyfile. To serve files with automatic HTTPS, replace its contents with:
example.com {
root * /var/www/example.com
file_server
}
Create the site and reload:
sudo mkdir -p /var/www/example.com
echo "<h1>Served by Caddy over HTTPS</h1>" | sudo tee /var/www/example.com/index.html
sudo systemctl reload caddy
Visit https://example.com โ Caddy has already fetched a certificate. That's the whole thing: name the domain, and HTTPS just happens.
Step 5: Reverse-proxy an app
The most common real use is putting Caddy in front of an app running on a local port. Say your Node.js app listens on port 3000:
app.example.com {
reverse_proxy localhost:3000
}
Reload:
sudo systemctl reload caddy
Now https://app.example.com securely proxies to your app, with TLS terminated by Caddy. This is dramatically simpler than the equivalent Nginx-plus-Certbot setup.
Handy Caddyfile patterns
Multiple sites โ just stack blocks:
site-a.com {
reverse_proxy localhost:3000
}
site-b.com {
root * /var/www/site-b
file_server
}
Gzip/zstd compression:
example.com {
encode zstd gzip
root * /var/www/example.com
file_server
}
Validate before reloading
Check your Caddyfile for errors:
caddy validate --config /etc/caddy/Caddyfile
Caddy vs Nginx
Nginx is the veteran with more tuning knobs and a bigger ecosystem โ reach for it on complex, high-traffic setups. Caddy wins on simplicity and automatic TLS, which makes it ideal for small-to-medium sites, side projects, and quickly fronting an app with HTTPS. On a Nxeon VPS with full root you can install either; if your goal is "secure site, minimum fuss," Caddy gets you there in about five minutes.