Caddy è un web server e reverse proxy open-source scritto in Go, noto per la sua semplicità di configurazione e per la gestione automatica dei certificati HTTPS tramite Let’s Encrypt. A differenza di altri web server come Nginx Reverse Proxy , Caddy abilita HTTPS di default senza richiedere configurazioni manuali, rendendo la messa in sicurezza dei propri servizi (anche all’interno della propria rete) un processo praticamente trasparente.

Tutta la configurazione avviene in modo dichiarativo tramite un unico file chiamato Caddyfile, con una sintassi semplice e intuitiva che lo rende accessibile anche a chi non ha grande esperienza con i web server. Oltre al reverse proxy, Caddy offre un supporto nativo al load balancing e alla compressione automatica.

Processo di Installazione

Caddy non è incluso nei repository ufficiali di Fedora, ma il team di sviluppo mantiene un repository COPR dedicato che permette di installarlo e aggiornarlo comodamente tramite il gestore pacchetti dnf. L’installazione richiede pochi passaggi: abilitare il repository, installare il pacchetto e configurare il servizio systemd.

Installazione dei Pacchetti

L’installazione di Caddy su Fedora richiede l’abilitazione di un repository esterno, dato che il pacchetto non è incluso nei repository ufficiali.

Installa i plugin DNF5

Per prima cosa è necessario installare i plugin aggiuntivi per DNF5, il gestore pacchetti di Fedora. Tra questi plugin è incluso il supporto per i repository COPR, indispensabile per il passaggio successivo.

bash
sudo dnf install dnf5-plugins

Abilita il repository COPR

Una volta installati i plugin, è possibile abilitare il repository COPR del team Caddy. COPR (Cool Other Package Repositories) è un servizio di Fedora che permette a sviluppatori e comunità di distribuire pacchetti RPM non inclusi nei repository ufficiali. Il prefisso @caddy indica che si tratta di un gruppo/organizzazione e non di un singolo utente.

bash
sudo dnf copr enable @caddy/caddy

Installa Caddy

A questo punto DNF sa dove trovare il pacchetto e possiamo procedere con l’installazione vera e propria di Caddy, che verrà scaricato insieme a tutte le sue dipendenze.

bash
sudo dnf install caddy

Aggiunta dei Plugin DNS

Per utilizzare la DNS Challenge di Let’s Encrypt è necessario aggiungere a Caddy i plugin specifici per il proprio provider DNS. Questi plugin non possono essere installati mentre il servizio è in esecuzione, quindi nel caso fosse in esecuzione sarà necessario come prima cosa fermarlo.

bash
sudo systemctl stop caddy

Una volta che siamo sicuri che il servizio non sia attivo, sarà possibile installare i plugin necessari tramite il comando caddy add-package. Questa operazione richiede qualche istante (dipende sempre dalla potenza della macchina e dalla velocità di connessione) in quanto Caddy dovrà scaricare e compilare i moduli richiesti direttamente sulla macchina (qui sotto installo quelli per Cloudflare e Infomaniak).

bash
sudo caddy add-package github.com/caddy-dns/cloudflare
sudo caddy add-package github.com/caddy-dns/infomaniak

Configurazione dei Token

Per poter utilizzare la DNS Challenge, Caddy avrà bisogno dei token API dei provider DNS configurati, in modo che possa eseguire le azioni di lettura/scrittura sui DNS (ogni servizio ha le sue procedure, che non saranno spiegate in questa guida). Per gestire queste credenziali in modo sicuro è possibile utilizzare un file environment di systemd, che verrà letto dal servizio all’avvio senza esporre i token nel Caddyfile o in altri file di configurazione accessibili.

Crea il file environment

Creiamo il file environment contenente i token.

bash
sudo nano /etc/caddy/environment

All’interno del file inseriamo i token dei provider DNS che abbiamo configurato nei passaggi precedenti.

CLOUDFLARE_API_TOKEN=il_tuo_token_cloudflare
INFOMANIAK_API_TOKEN=il_tuo_token_infomaniak

Proteggi i permessi del file

Una volta salvato il file, è importante proteggerne i permessi in modo che solo l’utente root e il gruppo caddy possano accedervi. Il comando chown assegna la proprietà del file a root con gruppo caddy, mentre chmod 640 imposta i permessi in modo che il proprietario possa leggere e scrivere il file, il gruppo possa solo leggerlo e tutti gli altri utenti non abbiano alcun accesso.

bash
sudo chown root:caddy /etc/caddy/environment
sudo chmod 640 /etc/caddy/environment

Configura systemd per caricare i token

Infine, è necessario indicare a systemd di caricare le variabili d’ambiente da questo file all’avvio del servizio Caddy. Per farlo utilizziamo il comando systemctl edit, che crea un override della configurazione del servizio senza modificare il file originale.

bash
sudo systemctl edit caddy

All’interno dell’editor che si aprirà, inseriamo le seguenti righe (dove dovremo inserire il percorso del file delle credenziali).

[Service]
EnvironmentFile=/etc/caddy/environment

Abilitazione del Servizio

Una volta completata l’installazione, è necessario abilitare il servizio in modo che si avvii automaticamente ad ogni riavvio del sistema e avviarlo immediatamente.

bash
sudo systemctl enable --now caddy

Con questo comando possiamo verificare che il servizio sia attivo e funzionante controllandone lo stato.

bash
systemctl status caddy

Perché Cloudflare?

Cloudflare ed Infomaniak non sono sponsor di questa guida. Sono semplicemente dei provider DNS che utilizzo e con cui questa configurazione è stata testata. Lo stesso approccio è applicabile ad altri provider supportati dal progetto caddy-dns .

Configurazione del Caddyfile

Il Caddyfile è il file di configurazione di Caddy, all’interno del quale vengono definiti tutti i domini, i sottodomini e i relativi comportamenti del reverse proxy. La sintassi è totalmente dichiarativa e qui sotto riporto alcuni esempi comuni, ma la configurazione completa è disponibile nella documentazione ufficiale .

Configurazione DNS Challenge (opzionale)

Questo blocco è necessario solo se si utilizza la DNS Challenge per ottenere i certificati Let’s Encrypt (come descritto nella sezione di installazione). Va inserito in testa al Caddyfile e contiene le opzioni globali, tra cui l’email per le notifiche di Let’s Encrypt e le credenziali del provider DNS (inserite nel docker-compose).

text
{
	# Email per notifiche Let's Encrypt
	email mario.rossi@dominio.xx

	# DNS Challenge globale via Cloudflare
	acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}

Configurazione Reverse Proxy

Questo è l’esempio più comune: instradare il traffico da un dominio (o sottodominio) verso un altro servizio, che può trovarsi sulla stessa macchina o in un altro container. Con questa configurazione Caddy otterrà automaticamente un certificato SSL per il dominio specificato e instraderà tutto il traffico verso il servizio in ascolto sulla porta 8080.

text
servizio.dominio.xx {
    reverse_proxy localhost:8080
}

Configurazione Reverse Proxy con Cache

Oltre al reverse proxy, è possibile definire le regole di cache specificando quali file il browser deve tenere in memoria (e per quanto tempo) e quali invece devono essere ricaricati ad ogni visita. Nell’esempio qui sotto, i file statici come immagini, CSS e JavaScript vengono mantenuti in cache per una settimana, mentre le pagine HTML vengono sempre richieste al server.

text
servizio.dominio.xx {
	reverse_proxy 80.81.82.83:1234

	@static path *.js *.css *.png *.jpg *.jpeg *.gif *.svg *.ico *.woff *.woff2 *.ttf *.eot
	header @static Cache-Control "public, max-age=604800, immutable"

  @html path *.html /
	header @html Cache-Control "no-cache"
}

Configurazione di un Redirect

In alcuni casi può essere necessario reindirizzare un dominio verso un altro, ad esempio per ridirigere la versione con www verso quella senza, oppure per spostare il traffico da un vecchio dominio a uno nuovo. In questo esempio, tutte le richieste verso www.dominio.xx vengono reindirizzate con un redirect permanente (HTTP 301) verso dominio.xx, mantenendo il percorso originale grazie a {uri}.

text
www.dominio.xx {
	redir https://dominio.xx{uri} permanent
}

Configurazione di Load Balancing

Caddy supporta nativamente il load balancing semplicemente specificando più destinazioni nella direttiva reverse_proxy. Il traffico verrà distribuito automaticamente tra i vari backend in modalità round-robin.

text
servizio.dominio.xx {
	reverse_proxy 10.0.0.1:8080 10.0.0.2:8080 10.0.0.3:8080
}

Volendo è possibile specificare una politica di distribuzione diversa, come ad esempio least_conn che seleziona il backend con il minor numero di connessioni attive, oppure random.

text
servizio.dominio.xx {
	reverse_proxy 10.0.0.1:8080 10.0.0.2:8080 10.0.0.3:8080 {
		lb_policy least_conn
	}
}

Primo Accesso ed Aggiornamento

Una volta completata l’installazione e avviato il container, Caddy inizierà immediatamente a servire i siti seguendo quanto dichiarato nel Caddyfile. Se i domini puntano correttamente al server, Caddy provvederà automaticamente ad ottenere e gestire i certificati HTTPS tramite Let’s Encrypt. Per verificare che tutto funzioni correttamente è possibile controllare i log con docker logs Caddy, dove si dovrebbe vedere il messaggio di ottenimento del certificato SSL.

Quando si modifica il Caddyfile, le modifiche non vengono applicate automaticamente al salvataggio del file. Per attivarle è necessario eseguire un reload esplicito all’interno del container:

bash
docker exec Caddy caddy reload --config /etc/caddy/Caddyfile

Questo approccio è un punto di forza di Caddy: il reload avviene in modo “graceful”, ovvero la nuova configurazione viene caricata senza interrompere le connessioni attive, garantendo virtualmente zero downtime. In questo modo è possibile aggiornare le regole di reverse proxy, aggiungere nuovi domini o modificare i comportamenti della cache con la certezza che il servizio non subirà interruzioni.

Troubleshooting & Consigli

Di seguito alcuni consigli utili per risolvere i problemi di configurazione più comuni:

  • Se Caddy non riesce ad ottenere i certificati SSL, verificare che le porte 80 e 443 siano raggiungibili dall’esterno e che il dominio punti correttamente all’indirizzo IP del server. Controllare i log con docker logs Caddy per dettagli.
  • Se il reverse proxy non funziona, assicurarsi che il servizio di destinazione sia raggiungibile dal container Caddy. Se il servizio è in un altro container Docker, utilizzare il nome del container o una rete Docker condivisa al posto di localhost.
  • Per utilizzare Caddy come reverse proxy verso altri container Docker, è consigliato creare una rete Docker dedicata e collegarvi sia Caddy che i servizi da esporre, in modo che possano comunicare tramite il nome del container.