Cos'è il canary deployment? Guida pratica per sviluppatori
Riassunto
Un canary deployment invia una nuova versione a una piccola quota di traffico reale, spesso dall'1% al 5%, prima che la ricevano tutti. Confronti tasso di errori e latenza con la versione stabile, allarghi la fetta se regge e riporti il peso del canary a zero se non regge. Limita i danni di una release difettosa, ma richiede metriche per versione e abbastanza traffico perché abbia senso.
Cos'è il canary deployment? È un rilascio in cui la nuova versione della tua app riceve per prima una piccola fetta di traffico reale, diciamo dall'1% al 5%, mentre tutti gli altri restano sulla versione vecchia. Tieni d'occhio il tasso di errori e la latenza su quella fetta. Se è sana, la allarghi. Se va male, rimandi il traffico indietro e quasi nessuno se ne accorge. È tutta l'idea, e il resto dell'articolo serve a farla funzionare davvero.

Perché si chiama canary?
I minatori portavano i canarini nelle gallerie perché gli uccelli reagivano ai gas tossici prima delle persone. Un canarino che smetteva di cantare era il segnale per uscire. Il deployment funziona allo stesso modo: un piccolo gruppo di utenti incontra per primo il codice nuovo e fa da sistema di allarme. Il glossario CNCF lo descrive come due ambienti, uno che serve il traffico reale e uno con il codice aggiornato, con il traffico spostato gradualmente, partendo da una quota piccola come l'1%.
In pratica il problema è questo: gli utenti del canary sono utenti veri. Lo staging non può darti questo. In produzione ci sono i browser strani, le cache vecchie, il cliente con il file di importazione da 40 MB. Il canary è il modo per incontrarli prima che li incontrino tutti i tuoi bug.
Come funziona davvero un canary deployment?
Quattro parti in gioco, niente di esotico.
Due versioni in esecuzione fianco a fianco. La vecchia (stabile) e la nuova (canary). Entrambe devono poter servire richieste nello stesso momento.
Uno splitter del traffico. Un load balancer, un ingress controller, un service mesh o una regola CDN che manda una percentuale configurabile verso il canary.
Metriche di cui ti fidi. Tasso di errori, latenza e almeno un segnale di business, come il successo del checkout o le registrazioni.
Una regola per avanzare o interrompere. Scritta prima del deploy, non inventata alle 23 mentre guardi i grafici.
Una rampa tipica va così: 1%, 5%, 25%, 50%, 100%, con una pausa a ogni passo. Anche Google Cloud Deploy segue la stessa forma: definisci una serie di percentuali e lo strumento distribuisce il traffico, con un esempio che usa fasi al 25%, 50% e 75% prima della versione stabile finale. La documentazione sui canary di Cloud Deploy mostra inoltre che ogni fase può eseguire un job di verifica e un'analisi per decidere se avanzare.
Non è un setup perfetto. È un setup fattibile. Non ti serve Kubernetes: una route pesata in nginx, una regola di Cloudflare Worker che imposta un cookie o due macchine Fly.io dietro un proxy contano tutte.
Come appare lo split del traffico in una configurazione?
Ecco l'esempio utile più piccolo, un upstream nginx con pesi. Nove richieste su dieci vanno alla stabile, una va al canary.
upstream app {
server 10.0.0.10:3000 weight=9; # stabile
server 10.0.0.11:3000 weight=1; # canary
}Questo ha un difetto che devi conoscere: lo split avviene per richiesta, quindi lo stesso utente può passare da una versione all'altra su due clic consecutivi. Se la nuova versione cambia la forma di una risposta API o di una colonna del database, quell'utente passerà un brutto momento. Il routing sticky per cookie o per ID utente risolve il problema, ed è la prima cosa da aggiungere una volta che lo split di base funziona.

Cosa guardare mentre il canary è attivo?
Confronta il canary con la versione stabile nello stesso momento, non con la settimana scorsa. La settimana scorsa aveva un traffico diverso. La domanda è sempre la stessa: il canary va peggio della versione che sta servendo il restante 95% adesso?
Tasso di errori. Risposte HTTP 5xx ed eccezioni non gestite, separate per etichetta di versione.
Latenza. p95 e p99, non la media. La media nasconde la coda lenta, dove si nascondono le regressioni.
Saturazione. CPU, memoria, connessioni al database. Una perdita di memoria si vede come una pendenza, quindi dagli tempo.
Una metrica di business. Se il successo del checkout scende sul canary mentre gli errori restano piatti, hai rilasciato un bug silenzioso.
L'errore che vediamo più spesso nei team piccoli è far avanzare la rampa a tempo. Cinque minuti all'1%, poi al 25%, indipendentemente da ciò che dicono i grafici. Con poco traffico, cinque minuti all'1% possono voler dire sei richieste, e non ti dicono nulla. Aspetta un numero minimo di richieste, non un numero minimo di minuti.
Gli strumenti che rendono tutto meno manuale meritano un'occhiata quando hai traffico reale.
Canary o blue-green: quale scegliere?
Il blue-green mantiene due ambienti completi e sposta tutto il traffico in un colpo solo. Il rollback significa rimettere il traffico sul vecchio, ed è veloce e pulito. Il costo è che per un attimo il 100% degli utenti è sulla nuova versione, e durante lo switch paghi il doppio dell'infrastruttura.
Il canary espone solo una fetta, quindi il raggio d'impatto è più piccolo. Il prezzo è la complessità: ti servono pesi sul traffico, metriche per versione e una regola di decisione. Il rollback consiste nel portare il peso del canary a zero, cosa rapida ma non letteralmente istantanea se le connessioni devono drenare.
Tre ragioni per scegliere il canary, una per non sceglierlo. Scegli il canary quando un bug in produzione costa caro, quando hai abbastanza traffico perché una piccola fetta abbia senso e quando puoi confrontare le metriche per versione. Evitalo quando hai qualche decina di utenti al giorno: la fetta del canary sarà statisticamente vuota e andrai a intuito. A quella scala, il blue-green o anche un deploy semplice con uno script di rollback veloce è la risposta onesta.
I rolling update stanno nel mezzo. Sostituiscono le istanze una alla volta, in modo delicato, ma non sono un esperimento controllato: non scegli chi vede la nuova versione e non confronti coorti.
Dove si inseriscono i feature flag?
Un canary deployment divide il traffico tra versioni del codice. Un feature flag divide il comportamento dentro una sola versione. Le due cose si confondono spesso, e la confusione costa cara.
Distribuisci il nuovo codice a tutti, nascosto dietro un flag spento. Poi accendi il flag per l'1% degli utenti, poi per il 10%, poi per tutti. Spesso si parla di release canary a livello di funzionalità. Il vantaggio: il rollback è girare un flag, senza rideploy. Lo svantaggio: il percorso di codice morto resta in produzione per tutti, e i flag dimenticati diventano debito tecnico.
Per chi sviluppa da solo, i flag sono di solito il primo passo più economico. Un booleano in una tabella di configurazione e un hash dell'ID utente ti danno l'80% del valore. Se ti serve di più, un servizio gestito si occupa di targeting, log di audit e rollout graduali in percentuale.

Cosa va storto con i canary nei progetti reali?
Testato. Non ottimale. Ecco perché lo facciamo lo stesso. Questi sono i problemi che mordono davvero.
Migrazioni del database. Entrambe le versioni colpiscono lo stesso database nello stesso momento. Se il canary elimina o rinomina una colonna, la stabile si rompe. La soluzione è il pattern expand and contract: aggiungi prima le nuove colonne, rilascia codice che gestisce entrambe le forme e rimuovi quelle vecchie solo in una release successiva. Se salti questo passaggio, il canary abbatte la versione stabile.
Sessioni con stato. Se le sessioni vivono in memoria su un'istanza, un utente che passa tra le versioni viene disconnesso. Sposta lo stato della sessione in uno store condiviso prima di provare i canary.
Cache avvelenate. Una nuova versione che scrive un formato di cache diverso può corrompere ciò che legge la vecchia. Versiona le chiavi della cache.
Job in background. Anche il canary consuma i messaggi delle code. Un worker difettoso può divorare job alla massima velocità, perché la percentuale di traffico non limita il consumo delle code. Dai al canary una coda o un peso di consumer dedicati.
Allarmi mai collegati. Il canary può fallire rumorosamente in una dashboard che nessuno apre. Un'interruzione automatica su una soglia batte una persona che guarda, soprattutto alle 2 di notte a Taipei o a Bangkok, quando l'unica persona sveglia è quella che ha fatto il deploy.
Come iniziare con un canary su un progetto personale?
Parti più in piccolo di quanto pensi. Sei uno sviluppatore, non un team di piattaforma.
Etichetta ogni metrica con una versione. Metti lo SHA di git in un header e nei log. Senza, non puoi confrontare canary e stabile.
Scegli una sola regola di interruzione. Per esempio: tasso di errori sul canary sopra il doppio della stabile per cinque minuti significa rollback. Una regola, scritta.
Aggiungi una route pesata. Pesi di nginx, una regola di Cloudflare o la funzione di split del traffico del tuo host. La maggior parte delle piattaforme gestite oggi offre il routing in percentuale senza strumenti extra.
Rilascia prima qualcosa di banale. Una modifica al testo, non la riscrittura della pagina dei prezzi. Prova la rampa e il rollback quando non c'è niente in gioco.
Cronometra il rollback. Eseguilo davvero una volta. Se ti servono dieci minuti di tentativi, quello è il problema da sistemare, non la rampa.
Se il tuo progetto è ancora nella fase in cui cerchi di capire chi lo pagherà, probabilmente è prematuro. Rilascia in modo semplice, tieni uno script di rollback e torna ai canary quando un'interruzione ti costerebbe clienti veri. Se sei già lì, la route pesata più una regola di interruzione sono un weekend di lavoro, e si ripagano la prima volta che una release difettosa muore all'1% invece che al 100%.
Bisogna usare il canary per tutto?
No. Modifiche di configurazione, ritocchi al testo e correzioni di un refuso nel footer non hanno bisogno di una rampa. Usa i canary per le modifiche in cui sbagliare costa denaro o fiducia: pagamenti, autenticazione, modelli di dati, tutto ciò che tocca il percorso critico. Una pipeline che fa la rampa su ogni commit per un'ora verrà aggirata la prima volta che qualcuno ha fretta, e un processo aggirato è peggio di nessun processo.
Quindi, qual è la modifica più rischiosa del tuo prossimo rilascio, e cosa servirebbe per mandarla prima all'1% degli utenti?