
Caddy is a high performance web server. It is actually 11 years old as of 2026. Strangely enough, Nginx is now 21 years old, and Apache web server is now 31 years old. Caddy is built with Golang.
Just as we migrated from Apache to Nginx, now it is time to migrate to Caddy.
Install caddy
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 chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
After this:
- Edit the Caddyfile
sudo nano /etc/caddy/Caddyfile
A very basic file is something like:
example.com {
root * /var/www/html
file_server
}
This basically means static files can be served from /var/www/html and the domain name will get automatically updated SSL certs. Note: may have to create the /www/html directories.
- Next, restart the server:
systemctl reload caddy
You'll have to poke 80 and 443 holes in the ufw or whatever firewall you are using.
Additional caddy configuration
A more featureful Caddyfile:
{
# General options
}
# redirect to https
http:// {
redir https://{host}{uri} permanent
}
# server
example.com {
root * /var/www/html
file_server
# enable access log
log {
output file /var/log/caddy/access.log
}
# enable error log
log {
output file /var/log/caddy/error.log
format console
level ERROR
}
# disallow MIME sniffing
header / {
X-Content-Type-Options nosniff
}
# disable server tokens
header / {
-Server
}
# break frames
header / {
X-Frame-Options SAMEORIGIN
}
# tell browser to stick with https
header / {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
}
Fail2Ban and caddy
Note that this is slightly different than using Fail2Ban with Nginx.
More to follow...