Traefik come reverse proxy su VPS Hetzner: HTTPS automatico e routing avanzato
Il 28 marzo 2025 mi ha contattato il socio di un'agenzia digitale lombarda specializzata in sviluppo Laravel e Symfony per clienti finali - 8 dipendenti, 14 clienti attivi con applicazioni in produzione hosted sulla loro infrastruttura, fatturato annuo di circa 980.000 euro. L'agenzia gestiva su un singolo VPS Hetzner CCX33 la produzione di 6 applicazioni Laravel e 3 API Symfony per i loro clienti, più due applicazioni di staging e un tool interno di monitoring - totale 12 applicazioni web su un VPS. La configurazione era basata su Nginx con virtual host separati, gestione manuale dei certificati Let's Encrypt via certbot in cron, deploy ciascuno con il suo script bash personalizzato. Il problema era il costo operativo cumulativo: ogni nuovo cliente richiedeva 2-3 ore di lavoro per configurare il virtual host Nginx, ottenere certificato, validare routing, e ogni deploy di cliente esistente richiedeva attenzione se coinvolgeva modifiche di routing o redirect. Il socio stimava che la gestione della configurazione reverse proxy occupasse circa 30 ore al mese del suo senior dev.
La soluzione che gli ho proposto è stata la migrazione a Traefik come reverse proxy, con service discovery automatico tramite label Docker e gestione automatica di certificati Let's Encrypt. In tre giornate di lavoro distribuite in due settimane, ho migrato le 12 applicazioni a un'infrastruttura Traefik con ciascuna app in container Docker, Traefik come reverse proxy unico, certificati gestiti automaticamente, dashboard web per visibilità real-time del routing. Dopo il go-live, l'operazione di aggiungere un nuovo cliente/applicazione alla produzione è diventata un pattern standardizzato che richiede 15-20 minuti invece di 2-3 ore: si aggiungono le label Docker appropriate al container dell'applicazione, si fa deploy, Traefik rileva automaticamente il nuovo servizio, richiede il certificato Let's Encrypt, inizia a instradare il traffico. Il costo operativo mensile di gestione del reverse proxy è sceso del 75%. Costo consulenziale dell'intervento: 3.400 euro.
Questo articolo descrive l'adozione di Traefik come reverse proxy moderno su VPS, basato sull'esperienza di circa 18 progetti simili negli ultimi quattro anni. Il principio guida è uno: Traefik è particolarmente adatto a contesti con molte applicazioni coresidenti su infrastruttura condivisa, dove l'automazione del service discovery e dei certificati produce ROI operativo immediato. Per scenari mono-applicazione il beneficio è marginale; per scenari multi-applicazione è trasformativo.
Perché Nginx è meraviglioso ma non scala bene operativamente con multiple app su stesso VPS
Nginx è un web server e reverse proxy eccellente, con performance e affidabilità testate da decenni di produzione su infrastrutture Internet di ogni scala. Non c'è nulla di sbagliato in Nginx come reverse proxy - è lo strumento di default per la stragrande maggioranza dei casi d'uso, e per applicazioni dedicate su VPS dedicati è ampiamente la scelta corretta. Il problema emerge quando si gestiscono molte applicazioni coresidenti su infrastruttura condivisa, tipico scenario di agenzie di sviluppo o software house che hanno più clienti con piccole-medie applicazioni.
Il limite operativo di Nginx in questi scenari ha tre dimensioni. Prima dimensione: configurazione statica per-app. Ogni nuova app richiede scrittura manuale di un file virtual host. Seconda dimensione: certificati gestiti a parte. Let's Encrypt tramite certbot funziona ma richiede cron schedulato, gestione del reload di Nginx post-rinnovo, monitoring dei fallimenti di rinnovo. Terza dimensione: zero visibilità runtime. Quando qualcosa va storto nel routing, l'unico modo di diagnosticare è leggere log e configuration file - nessuna dashboard centralizzata.
Traefik affronta le tre dimensioni con approccio completamente diverso. Service discovery automatico: Traefik legge la configurazione dei servizi direttamente dalle label Docker (o da altri provider come Kubernetes, Consul, file statici), quindi aggiungere un servizio non richiede modifiche alla configurazione Traefik stessa. Let's Encrypt integrato: Traefik richiede e rinnova automaticamente i certificati per tutti i domini che serve, senza configurazione aggiuntiva. Dashboard web nativa: Traefik espone una UI web che mostra in tempo reale tutti i router, i servizi, i middleware, lo stato dei certificati. La documentazione ufficiale di Traefik è eccellente e copre in dettaglio configurazione e integrazione, ed è il riferimento canonico per l'adozione.
Se stai gestendo multiple applicazioni web su VPS condiviso e spendi tempo significativo in configurazione reverse proxy, nel mio profilo professionale trovi il dettaglio degli interventi di razionalizzazione infrastruttura con Traefik che ho condotto in contesti PMI italiane, sempre con approccio pragmatico e calibrato sulla capacità operativa del team.
Setup base di Traefik con Docker Compose: il pattern di produzione
Il pattern di deployment di Traefik che applico in produzione è basato su Docker Compose (coerente con i pattern per Docker Compose in produzione su VPS che ho descritto in un articolo dedicato). Traefik gira come servizio nel compose, espone le porte 80 e 443 sull'host, monta il socket Docker per leggere la configurazione dei container vicini, ha un volume persistente per i certificati Let's Encrypt.
Il file compose.yaml del servizio Traefik è:
services:
traefik:
image: traefik:v3.2
restart: unless-stopped
container_name: traefik
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /srv/traefik/letsencrypt:/letsencrypt
- ./traefik.yml:/etc/traefik/traefik.yml:ro
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$2y$$05$$..."
networks:
traefik-public:
external: trueIl file di configurazione statica traefik.yml:
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
network: traefik-public
certificatesResolvers:
letsencrypt:
acme:
email: "[email protected]"
storage: "/letsencrypt/acme.json"
httpChallenge:
entryPoint: web
api:
dashboard: true
log:
level: INFOQuesti due file insieme definiscono l'intera infrastruttura reverse proxy: entry point HTTP/HTTPS con redirect automatico HTTP→HTTPS, service discovery automatico dai container Docker sulla rete traefik-public, richiesta automatica di certificati Let's Encrypt, dashboard web accessibile con basic auth sul dominio traefik.example.com.
Come un'applicazione dichiara la sua configurazione via label Docker
Una volta che Traefik è in esecuzione, un'applicazione dichiara la sua configurazione di routing tramite label Docker nel suo compose. Questo è il pattern che rende l'aggiunta di nuovi servizi così veloce: niente modifica della configurazione Traefik, niente restart di Traefik, niente edit di file remoti. Basta lanciare il container con le label appropriate.
Esempio di configurazione completa per un'applicazione Laravel cliente:
services:
acme-ecommerce:
image: acme/ecommerce:1.4.2
restart: unless-stopped
networks:
- traefik-public
- acme-internal
labels:
- "traefik.enable=true"
- "traefik.http.routers.acme-ecommerce.rule=Host(`shop.acme.com`)"
- "traefik.http.routers.acme-ecommerce.entrypoints=websecure"
- "traefik.http.routers.acme-ecommerce.tls.certresolver=letsencrypt"
- "traefik.http.services.acme-ecommerce.loadbalancer.server.port=80"
- "traefik.http.middlewares.acme-security.headers.stsseconds=31536000"
- "traefik.http.middlewares.acme-security.headers.contenttypenosniff=true"
- "traefik.http.middlewares.acme-security.headers.framedeny=true"
- "traefik.http.routers.acme-ecommerce.middlewares=acme-security"Le label esprimono: abilita questo container in Traefik, il router deve matchare Host shop.acme.com, usa entry point websecure (HTTPS), richiedi certificato Let's Encrypt tramite resolver letsencrypt, il container ascolta internamente sulla porta 80, applica middleware di security header. Quando il container parte, Traefik in meno di un secondo rileva le label, richiede il certificato se non presente, inizia a instradare il traffico.
L'operazione di aggiungere un nuovo cliente diventa: creare il file compose.yaml con le label appropriate, fare docker compose up -d, aspettare 30-60 secondi che il certificato venga emesso. Zero modifiche a Traefik, zero restart, zero configurazione di virtual host.
Middleware stack: security headers, rate limiting, basic auth, redirect
Uno dei vantaggi operativi di Traefik è la libreria di middleware riutilizzabili che coprono la maggioranza dei pattern di configurazione tipici. I middleware si applicano ai router tramite label e possono essere riutilizzati su più servizi. Quelli che configuro di default in produzione sono cinque.
Security headers: aggiunge header HTTP di sicurezza standard (HSTS, X-Content-Type-Options, X-Frame-Options, Content-Security-Policy) che rinforzano la postura di sicurezza delle applicazioni servite. Attivo di default su ogni router.
Rate limiting: limita il numero di richieste al secondo da un singolo IP per prevenire abuse e brute force. Configurazione tipica: 100 req/s con burst di 200, per endpoint pubblici.
Basic auth: protezione password-based per aree riservate (staging environments, dashboard amministrative). Integrazione con htpasswd file o con servizi di autenticazione esterna.
Redirect regex: redirezioni complesse via regex, utili per migrazioni di URL, redirect da www a non-www, redirect di lingua.
IP whitelist: restringe accesso a specifici range IP, utile per interfacce amministrative che non dovrebbero essere pubbliche ma anche per protezione temporanea durante incident response.
Il pattern di middleware si integra con i principi di SSH hardening avanzato su VPS che ho descritto in un articolo dedicato - Traefik aggiunge al livello HTTP le stesse protezioni strutturali che SSH fornisce al livello transport.
Certificate management automatico: Let's Encrypt con rinnovo trasparente
Il componente che automatizza la gestione dei certificati è uno dei valori più alti di Traefik. Per ogni dominio dichiarato con certresolver=letsencrypt, Traefik esegue automaticamente il flusso di challenge HTTP (o DNS, configurabile) per ottenere il certificato, memorizza il certificato nel volume persistente, e avvia il flusso di rinnovo quando il certificato si avvicina alla scadenza (tipicamente 30 giorni prima).
Il pattern standard con HTTP challenge richiede che la porta 80 sia aperta al mondo e che Traefik sia accessibile sull'HTTP prima di avere HTTPS. Questo funziona bene per la maggioranza dei casi ma ha un limite: non funziona se il DNS dell'applicazione non punta ancora al VPS al momento del deploy. Per scenari più complessi, uso DNS challenge dove Traefik interagisce direttamente con il DNS provider tramite API per validare il dominio senza necessità di connettività HTTP. Traefik supporta oltre 100 provider DNS nativamente.
La persistenza dei certificati nel file acme.json è critica per evitare di richiederli di nuovo a ogni restart di Traefik (Let's Encrypt ha rate limit che si triggerano facilmente). Il pattern di backup che applico include snapshot settimanale del volume letsencrypt/ su storage separato - in caso di disastro, il restore del volume preserva tutti i certificati.
Pattern di deploy zero-downtime con Traefik
Uno dei vantaggi operativi sottostimati di Traefik è il pattern di deploy zero-downtime naturale. Con Traefik, il deploy di una nuova versione di un'applicazione può seguire il pattern blue-green semplificato con minimo sforzo.
Il workflow è: avviare il nuovo container acme-ecommerce-v2 in parallelo al vecchio acme-ecommerce-v1, entrambi sulla rete traefik-public ma con label diverse. Traefik vede entrambi ma il router Host matcha solo su acme-ecommerce-v1.rule=Host(shop.acme.com). Dopo verifica che v2 funzioni (accedendolo tramite label temporanea tipo Host('v2.shop.acme.com')), si modifica il label di v2 per matchare il Host principale e si rimuove il container v1. Traefik rileva il cambiamento in <1 secondo, il traffico inizia a fluire verso v2, zero downtime per l'utente. L'intero pattern si integra con le pipeline CI/CD moderne come quelle che ho descritto nel mio articolo sul deploy Laravel su VPS unmanaged con GitHub Actions.
Il risultato finale dell'intervento sull'agenzia lombarda a sei mesi dal go-live è stato il seguente. Tempo per aggiungere una nuova applicazione cliente alla produzione: sceso da 2-3 ore a 15-20 minuti (riduzione dell'85%). Tempo per gestire certificati Let's Encrypt: scende effettivamente a zero - tutto automatico, nessun intervento manuale richiesto in sei mesi. Dashboard Traefik consultata dal senior dev come prima cosa quando qualcosa va storto - visibilità immediata su tutti i 12 servizi attivi. Downtime totale di deploy nei sei mesi: zero (pattern blue-green). Bug operativi attribuibili a configurazione reverse proxy: zero. Tempo totale speso dal senior dev in gestione infrastruttura reverse proxy: sceso da 30 ore al mese a circa 4 ore al mese. Risparmio operativo annuo: 312 ore × tariffa interna ≈ 28.000 euro.
Se gestisci un'infrastruttura con molte applicazioni coresidenti su VPS condiviso e spendi tempo significativo in gestione manuale della configurazione reverse proxy, vale la pena valutare seriamente la migrazione a Traefik. Il ROI operativo è tipicamente visibile nei primi tre mesi, e il beneficio si accumula nel tempo con ogni nuova applicazione aggiunta. Se vuoi confrontarti sul tuo caso specifico con una proposta di migrazione calibrata sulla tua infrastruttura, contattami per una consulenza preliminare: in una sessione di analisi guidata produciamo insieme una mappatura delle tue attuali configurazioni Nginx, un disegno di architettura Traefik equivalente, e una roadmap di migrazione incrementale senza interruzioni delle applicazioni in produzione.