Torna al blog
Agosto 19, 2026Guide

Come installare il server web Caddy con HTTPS automatico

Installare Caddy su Ubuntu dal repository ufficiale, scrivere un Caddyfile per siti statici e reverse proxy, capire i certificati automatici, systemd, i log e gli errori comuni nella migrazione da Nginx.

Come installare il server web Caddy con HTTPS automatico

Caddy è un server web che ottiene e rinnova i certificati TLS per impostazione predefinita. Per un VPS piccolo che ospita uno o due domini, questo elimina un’intera classe di timer Certbot e file di snippet Nginx. Il linguaggio di configurazione (Caddyfile) è breve. Reverse proxy, gzip e HTTP/2 sono funzioni normali, non un weekend di moduli extra.

Nginx resta la scelta giusta per alcuni team: avete già config collaudate, o vi serve un modulo molto specifico. Questa guida è per l’altro caso comune: volete un HTTPS che funzioni su un VPS Hiddence nuovo senza memorizzare snippet include. Installiamo Caddy dal repo apt ufficiale, spieghiamo come parla con Let's Encrypt, serviamo un sito statico, facciamo proxy di un’app locale, ospitiamo più domini, guardiamo i log e copriamo le solite lotte per la porta 80 con Apache o un Nginx vecchio.

Quando Caddy è una buona scelta

L’HTTPS automatico è il titolo, ma il guadagno quotidiano sono meno parti in movimento. Caddy ascolta su 80 e 443, reindirizza HTTP verso HTTPS e memorizza i certificati nella propria directory dati. Ti serve comunque un dominio che punti al VPS. Non devi comunque rompere ACME (firewall 80/tcp, nessun altro processo che ruba :80). I certificati wildcard richiedono un modulo provider DNS: è un percorso più lungo di un certificato per un solo host.

  • Reindirizzamento HTTP→HTTPS automatico e rinnovo dei certificati
  • Caddyfile leggibile invece di lunghi blocchi server
  • Reverse proxy capace per Node, Python, PHP-FPM con config extra, o backend Docker
  • HTTP/2 e default TLS moderni senza un foglio di cipher
  • Unità systemd dal pacchetto ufficiale

Requisiti

Un dominio deve risolvere su questo VPS prima che Caddy possa dimostrare ACME HTTP-01. Se il DNS sta ancora propagandosi, Caddy fallirà l’emissione e riproverà: sembra «Caddy è rotto» quando è solo DNS. Ferma prima Apache o Nginx se possiedono 80/443.

  • Ubuntu 22.04 o 24.04
  • Un record A del dominio verso l’IP del VPS (e AAAA se usi IPv6)
  • Porte 80 e 443 libere e consentite nel firewall
  • Root o sudo

Passo 1: Installare Caddy dal repository ufficiale

Non installare un Caddy vecchio a caso da Ubuntu Universe se vuoi il comportamento TLS e ACME attuale. Il progetto Caddy documenta una sorgente apt. Dopo l’installazione esiste l’utente caddy e il servizio è abilitato.

bash
ssh root@YOUR_VPS_IP
apt update && apt -y install debian-keyring debian-archive-keyring apt-transport-https curl gpg

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 -y install caddy

caddy version
systemctl status caddy --no-pager

Passo 2: Primo Caddyfile — sito statico

Il Caddyfile predefinito è /etc/caddy/Caddyfile. Sostituiscilo con il tuo dominio. Caddy proverà a ottenere un certificato appena la config si carica se l’hostname non è localhost. Metti i file del sito in una directory leggibile dall’utente caddy (spesso permessi in stile www-data, ma il pacchetto usa l’utente caddy).

bash
mkdir -p /var/www/example
echo '<h1>It works</h1>' > /var/www/example/index.html
chown -R caddy:caddy /var/www/example

cat >/etc/caddy/Caddyfile <<'EOF'
example.com {
    root * /var/www/example
    file_server
    encode gzip
}
EOF

caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy

# Watch issuance:
journalctl -u caddy -f

Passo 3: Reverse proxy di un’applicazione locale

Se Gunicorn, Node o Docker ascoltano su 127.0.0.1:8000, Caddy deve essere l’unico processo pubblico. La direttiva reverse_proxy inoltra Host e le intestazioni X-Forwarded-* in modo ragionevole per la maggior parte delle app. Se l’app genera URL HTTP assolute, imposta i flag di proxy fidato / HTTPS nell’app (Django SECURE_PROXY_SSL_HEADER, Express trust proxy e così via).

bash
app.example.com {
    encode gzip
    reverse_proxy 127.0.0.1:8000
}

# Several hosts in one file are normal:
# blog.example.com {
#     root * /var/www/blog
#     file_server
# }

Passo 4: Firewall e systemd

Consenti 80 e 443. L’unità di Caddy è caddy.service; un reload basta dopo le modifiche al Caddyfile se il processo è sano. Se cambi variabili d’ambiente per un plugin DNS, un riavvio completo è più chiaro. I certificati vivono per impostazione predefinita sotto /var/lib/caddy/.local/share/caddy/: includi quel percorso nei backup se ti interessano i limiti di frequenza in una reinstallazione.

bash
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

systemctl enable --now caddy
systemctl reload caddy

# Backup cert storage (path may vary slightly by version):
ls -la /var/lib/caddy/

Passo 5: Log, compressione e intestazioni

I log di accesso aiutano quando un bot martella un percorso o quando fai debug dei 404. Puoi registrare per sito. Aggiungi intestazioni di sicurezza se ospiti un’app browser; non copiare un enorme pacchetto di intestazioni senza capire HSTS (una volta impostato un max-age lungo, i browser lo ricordano).

bash
example.com {
    root * /var/www/example
    file_server
    encode gzip
    log {
        output file /var/log/caddy/example.log
    }
    header {
        X-Content-Type-Options nosniff
        Referrer-Policy no-referrer-when-downgrade
        -Server
    }
}

mkdir -p /var/log/caddy
chown caddy:caddy /var/log/caddy
systemctl reload caddy

Passo 6: PHP e altri extra

Caddy può parlare con PHP-FPM con la direttiva php_fastcgi. Basta per molti hosting WordPress o Laravel, ma ti serve ancora php-fpm installato e un percorso socket che coincida. Se hai già un config PHP Nginx perfetto, migrare in una serata è facoltativo: Caddy brilla di più su reverse proxy + statico + TLS automatico.

bash
example.com {
    root * /var/www/example
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
}

# Confirm FPM is running:
systemctl status php8.3-fpm

Migrare da Nginx senza sorprese di downtime

Ferma Nginx prima di avviare Caddy o si batteranno per 80/443. Abbassa il TTL DNS il giorno prima se stai anche spostando gli IP. Prova con curl --resolve per colpire il nuovo VPS prima di cambiare il record A. Tieni i config Nginx in git per una settimana nel caso serva tornare indietro.

  • systemctl stop nginx && systemctl disable nginx
  • Installa Caddy, valida il Caddyfile, avvia Caddy
  • curl -I --resolve example.com:443:NEW_IP https://example.com
  • Solo allora cambia il DNS se l’IP è nuovo
  • La riemissione è automatica; non far girare anche Certbot contro lo stesso hostname

Risoluzione dei problemi

I fallimenti ACME sono quasi sempre DNS, firewall o un altro servizio sulla porta 80. Le righe di log di Caddy menzionano tls.obtain. Se il sito funziona in HTTP ma non in HTTPS, l’emissione non è mai stata completata. Se vedi troppi certificati, hai toccato i limiti di frequenza Let's Encrypt: usa la CA di staging per i test, non quella di produzione.

  • validate fallisce: sintassi del Caddyfile, graffa mancante
  • permission denied su root: chown caddy per la directory del sito
  • bind: address already in use — ss -tulpn | grep -E ':80|:443'
  • timeout del certificato: dig +short del dominio dal VPS, ufw allow 80
  • 502 reverse_proxy: backend spento, o hai fatto proxy verso localhost da una rete di container in modo errato

Note di sicurezza

I default TLS di Caddy sono conservativi. Il tuo lavoro è la sicurezza dell’applicazione e SSH. Non attivare l’API di amministrazione Caddy su un’interfaccia pubblica. L’endpoint di amministrazione predefinito è locale; lascialo così. Se usi un Caddyfile da internet, leggi ogni matcher: uno snippet che fa reverse_proxy di /* verso un IP interno può diventare un proxy aperto.

  • Non esporre l’API di amministrazione
  • Tieni il pacchetto aggiornato
  • HSTS solo dopo esserti assicurato che HTTPS funzioni per tutti gli hostname
  • Separa gli hostname di test e di produzione per proteggere i limiti di frequenza ACME

Consigli

  • caddy fmt --overwrite /etc/caddy/Caddyfile tiene il file leggibile
  • Usa snippet import quando hai molti siti simili
  • Per Docker è comune l’immagine caddy:alpine con un Caddyfile montato
  • I certificati wildcard richiedono un modulo DNS e un token API: proteggi quel token
  • Leggi journalctl -u caddy prima di riscrivere l’intero file

Caddy su un VPS è: pacchetto ufficiale, un Caddyfile breve, porte 80/443 aperte, DNS già puntato al server e reload systemd dopo le modifiche. Usalo come server di file statici o come reverse proxy davanti a Gunicorn, Node o Docker. L’HTTPS automatico funziona quando ACME può rispondere sulla porta 80; se l’emissione fallisce, sistema DNS e conflitti di porta prima di incolpare Caddy. Fai il backup di /var/lib/caddy se reinstalli spesso.