Configurare HTTPS per i propri servizi self-hosted è spesso percepito come un'operazione complessa: certificati da generare, rinnovi da automatizzare, configurazioni Nginx piene di direttive criptiche. Caddy nasce proprio per eliminare questa frizione, offrendo HTTPS automatico out-of-the-box tramite Let's Encrypt, con una configurazione che sta in poche righe leggibili.
In questa guida vediamo come usare Caddy come reverse proxy per esporre uno o più servizi locali su un dominio, con certificati TLS gestiti automaticamente.
Perché Caddy e non Nginx
Nginx resta uno standard solido e performante, ma richiede passaggi manuali per ottenere e rinnovare certificati TLS (tipicamente tramite Certbot) e una configurazione più verbosa per casi d'uso comuni.
Caddy gestisce automaticamente:
- La richiesta del certificato a Let's Encrypt al primo avvio
- Il rinnovo automatico prima della scadenza
- Il redirect da HTTP a HTTPS
- Gli header di sicurezza moderni con configurazione minima
Per chi gestisce pochi servizi su un singolo server (uno scenario molto comune nel self-hosting), questo si traduce in un risparmio di tempo reale e in una superficie di configurazione molto più piccola da mantenere.
Prerequisiti
- Un server Linux con un IP pubblico (una VPS è sufficiente)
- Un dominio (o sottodominio) che punti all'IP del server tramite un record DNS di tipo A
- Le porte 80 e 443 libere e raggiungibili dall'esterno
Installazione
Su sistemi Debian/Ubuntu, il modo più pulito è aggiungere il repository ufficiale:
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
Su Fedora/RHEL:
sudo dnf install 'dnf-command(copr)'
sudo dnf copr enable @caddy/caddy
sudo dnf install caddy
Dopo l'installazione, il servizio è già gestito da systemd:
sudo systemctl enable --now caddy
sudo systemctl status caddy
Il file di configurazione: Caddyfile
Tutta la configurazione di Caddy vive in un unico file, per convenzione /etc/caddy/Caddyfile. La sintassi è pensata per essere leggibile anche senza documentazione sottomano.
Esempio minimale: un servizio singolo
Supponiamo di avere un'applicazione che gira in locale sulla porta 3000 (ad esempio un dashboard Node.js o una webapp Python) e di volerla esporre su app.tuodominio.com:
app.tuodominio.com {
reverse_proxy localhost:3000
}
Tutto qui. Salvando questo file e ricaricando Caddy:
sudo systemctl reload caddy
Caddy si occupa automaticamente di:
- Validare il dominio tramite challenge ACME
- Ottenere il certificato da Let's Encrypt
- Configurare il redirect HTTP→HTTPS
- Avviare il proxy verso il servizio locale
In meno di un minuto, https://app.tuodominio.com è raggiungibile con un certificato valido.
Esempio con più servizi
Per chi, come spesso accade nel self-hosting, gestisce più applicazioni sullo stesso server, ogni blocco del Caddyfile rappresenta un dominio o sottodominio diverso:
dashboard.tuodominio.com {
reverse_proxy localhost:3000
}api.tuodominio.com {
reverse_proxy localhost:8080
}
git.tuodominio.com {
reverse_proxy localhost:3001
}
Ogni blocco ottiene il proprio certificato TLS in modo completamente indipendente, senza configurazione aggiuntiva.
Aggiungere header di sicurezza
Per un setup di produzione, è buona pratica aggiungere alcuni header di sicurezza standard:
app.tuodominio.com {
reverse_proxy localhost:3000 header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
Autenticazione di base per servizi interni
Se un servizio non ha un proprio sistema di autenticazione (ad esempio un dashboard di monitoring esposto temporaneamente) Caddy può aggiungere un layer di Basic Auth direttamente nel proxy:
monitor.tuodominio.com {
basicauth /* {
admin $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
}
reverse_proxy localhost:9090
}
La password hashata si genera con:
caddy hash-password --plaintext "la-tua-password"
Load balancing tra più istanze
Se un servizio gira su più porte o più host per ridondanza, Caddy bilancia automaticamente il traffico:
api.tuodominio.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy round_robin
}
}
Logging
Per avere visibilità sulle richieste in arrivo, è sufficiente aggiungere una direttiva log:
app.tuodominio.com {
reverse_proxy localhost:3000
log {
output file /var/log/caddy/app.log
format json
}
}
I log in formato JSON sono facilmente ingeribili da strumenti come jq per analisi rapide o da uno stack di log aggregation se il setup cresce di complessità.
Verifica e debug
Per controllare che la sintassi del Caddyfile sia corretta prima di applicare le modifiche:
sudo caddy validate --config /etc/caddy/Caddyfile
Per seguire i log in tempo reale e individuare eventuali problemi (DNS non propagato, porta del servizio locale errata, ecc.):
sudo journalctl -u caddy -f
Un errore comune è dimenticare che il dominio deve effettivamente puntare all'IP del server prima di ricaricare la configurazione: se il record DNS non è ancora propagato, la validazione ACME fallisce e Caddy ritenterà automaticamente, ma vale la pena verificare con:
dig +short app.tuodominio.com
confrontando il risultato con l'IP pubblico del server.
Conclusione
Caddy riduce la configurazione di un reverse proxy con HTTPS automatico a poche righe dichiarative, eliminando completamente la gestione manuale dei certificati. Per chi gestisce servizi self-hosted — dashboard personali, API interne, strumenti di sviluppo esposti temporaneamente — rappresenta probabilmente il modo più rapido per ottenere un setup sicuro e production-ready senza dover diventare esperti di configurazione TLS.
