HTTPS with Caddy
In 2021, I wrote about setting up HTTPS with nginx and swag.
But, I’ve found a much simpler approach recently using Caddy.
Caddy is an easy-to-configure reverse proxy which enables HTTPS by default.
The TLS certificates are issued by Let’s Encrypt, and caddy automatically renews them for you.
To install it, follow the documentation; here is the debian installation section:
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
Caddy is installed as a new service, which continues to run even after you reboot your server.
# Use the service command to manage the "caddy" service.
service caddy status
service caddy restart
# Or systemctl, if you prefer that option.
systemctl status caddy
The service, by default, points to the /etc/caddy/Caddyfile; create one if it doesn’t exist.
touch /etc/caddy/Caddyfile
You need to have a domain with an A record pointing to your server’s IP address.
Here’s how to do that on Cloudflare, Namecheap, or GoDaddy.
Assuming your local HTTP based service is running on port 8080 …
# For example, the comment section on this blog is handled by remark42.
# Here is the relevant portion of my docker-compose.yml
services:
remark:
image: umputun/remark42:latest
container_name: "remark"
restart: always
ports:
- "127.0.0.1:8080:8080"
environment:
# redacted
volumes:
- /var/lib/remark:/srv/var
Update the Caddyfile and restart the service.
# /etc/caddy/Caddyfile
yourdomain.com {
reverse_proxy * 127.0.0.1:8080
}
service caddy restart
After a minute or so, you should be able to open https://yourdomain.com using a web browser.
To see the service logs, use the journalctl command.
journalctl -f -u caddy
Here is more a complex example.
myblog.com {
# serve the html/css/js files from /root/app
root * /root/app
file_server
# Api calls go to 3001 on localhost
reverse_proxy /api/* 127.0.0.1:3001
}
# comment section on a subdomain
remark.myblog.com {
reverse_proxy * 127.0.0.1:8080
}
See the Common Patterns section of the docs for more advanced features.