“Funziona in prod” — è la frase che uno sviluppatore dice quando un bug non si riproduce in produzione, mentre sullo staging o sulla macchina locale l’errore si manifesta in modo stabile. Il problema è quasi sempre causato da una divergenza degli ambienti: versioni diverse delle dipendenze, file di configurazione, stato del database o impostazioni del server. Secondo i dati dell’analisi Stack Overflow Developer Survey 2024, il 43% degli sviluppatori almeno una volta al mese si trova in una situazione in cui il codice funziona sulla macchina locale ma fallisce in produzione. Analizziamo perché si verifica questa divergenza e come prevenirla.
Punti chiave
“Funziona in prod” — è un’espressione consolidata nell’ambiente degli sviluppatori che indica una situazione in cui il codice funziona sul server di produzione ma si rifiuta di funzionare nell’ambiente di test o sulla macchina locale di un collega. Esternamente sembra “nessun problema” anche se in realtà il problema esiste — semplicemente non si riproduce nell’ambiente di produzione. La radice della divergenza risiede nella differenza di configurazioni, versioni e dati tra gli ambienti.
L’espressione è nata come antitesi di un’altra famosa scusa — “Sulla mia macchina locale funziona”. Se uno sviluppatore dice “funziona in locale”, significa che il bug esiste solo per gli altri. E se “funziona in prod” — il bug esiste solo sullo staging o nell’ambiente di test, mentre la produzione è pulita. Ironia della sorte: in entrambi i casi il problema è reale, semplicemente non si manifesta a chi sta guardando. Secondo lo studio DevOps Research and Assessment (DORA) 2023, i team con un alto livello di automazione del deploy incontrano queste divergenze 3 volte meno spesso.
Dal punto di vista aziendale, la situazione “funziona in prod” è più pericolosa di quanto sembri. Se il bug è presente sullo staging ma non in prod, lo sviluppatore potrebbe ignorarlo — e al prossimo deploy l’errore passerà in produzione. Un sollievo temporaneo si trasforma in un problema futuro che dovrà essere risolto sotto la pressione degli utenti.
La ragione psicologica della persistenza dell’espressione — il riflesso di difesa. Uno sviluppatore che vede un bug sullo staging ma non in prod può inconsciamente minimizzare il problema: “se tutto va bene in produzione, allora non è urgente”. Un classico bias cognitivo — l’errore del sopravvissuto, dove il successo visibile della produzione supera la potenziale minaccia di un futuro guasto.
La seconda ragione — la responsabilità diluita. Se la produzione funziona ma lo staging no, la colpa è dell’ambiente, non del codice. Lo sviluppatore si scarica la responsabilità del bug, trasferendola all’ingegnere DevOps o all’amministratore. Secondo l’Atlassian State of DevOps 2022, nei team senza un ambiente di deploy unificato (Docker, Kubernetes), questi scarichi di responsabilità avvengono il 60% più spesso.
La terza ragione — la paura di un rilascio con zero downtime. Se lo sviluppatore corregge il bug sullo staging e distribuisce la correzione, ciò richiede un nuovo code review, test e deploy. L’espressione “funziona in prod” permette di rimandare la correzione al prossimo rilascio, riducendo il carico attuale. Una correzione rimandata — una delle principali cause di accumulo del debito tecnico nei team.
La produzione e lo staging non sono mai completamente identici — è tecnicamente impossibile a causa delle differenze di scala, carico e dati. Tuttavia, i parametri chiave devono coincidere: versione del sistema operativo, compilatore, interprete, database, web server e tutte le dipendenze del progetto. Se almeno un parametro differisce — il comportamento del codice può cambiare.
Le principali differenze tra gli ambienti includono:
La containerizzazione risolve la maggior parte di questi problemi. L’immagine Docker costruita per la produzione dovrebbe essere utilizzata anche sullo staging. L’unica differenza — le variabili d’ambiente e i mount dei volumi. Secondo il Docker State of Application Development 2023, i team che utilizzano un’immagine unificata per tutti gli ambienti riducono il numero di divergenze del 74%.
| Parametro | Ambiente locale | Staging | Produzione |
|---|---|---|---|
| OS | macOS / Windows | Server Linux | Server Linux |
| Database | SQLite / MySQL locale | Cluster MySQL | Cluster MySQL con replica |
| Carico | 1 utente | Simulazione 10–100 | 1000+ reali |
| Dati | Fixture | Maschera ti | Reali |
| CDN / cache | No | Parzialmente | Completamente |
La prima e più frequente causa — versioni diverse delle dipendenze. Lo sviluppatore installa un pacchetto localmente con il flag --save ma dimentica di aggiornare il package.json o il lock-file. Al deploy in prod viene installata una versione diversa che si comporta in modo differente. Per l’ecosistema npm, il lock-file risolve completamente il problema, per gli altri gestori di pacchetti — meccanismi simili (Gemfile.lock, Podfile.lock, pubspec.lock).
La seconda causa — variabili d’ambiente mancanti o superflue. Lo sviluppatore utilizza un file .env sulla macchina locale ma non aggiunge le variabili corrispondenti nel pipeline CI/CD o sul server. Risultato — il codice fallisce con un errore di connessione all’API o al database. Secondo il GitLab DevSecOps Survey 2023, il 27% degli incidenti in prod è correlato a variabili d’ambiente errate.
La terza causa — lo stato del database. Sullo staging, il DB può contenere record assenti in prod, o viceversa — migrazioni mancanti. Scenario tipico: lo sviluppatore scrive codice che utilizza un nuovo campo in una tabella, ma la migrazione non è stata ancora applicata in prod. Una strategia di migrazione con retrocompatibilità — l’unico modo per evitare tali situazioni.
La quarta causa — impostazioni regionali e linguistiche. La formattazione delle date, i separatori decimali, la codifica del testo — tutto questo può differire sulla macchina locale dello sviluppatore e sul server. Particolarmente rilevante per progetti con internazionalizzazione. Soluzione — specificare esplicitamente la locale nella configurazione dell’applicazione e non fare affidamento sulle impostazioni di sistema.
Primo passo — confrontare i log di entrambi gli ambienti. La differenza nel livello di logging spesso nasconde la causa: in prod potrebbe essere attivato INFO, mentre sullo staging DEBUG. Impostate lo stesso livello di logging e assicuratevi che entrambi gli ambienti scrivano in un formato che permetta il confronto automatico. Utilizzate sistemi centralizzati di raccolta log — Sentry, Datadog, ELK Stack.
Secondo passo — verificare le versioni delle dipendenze. Confrontate i lock-file, visualizzate l’elenco dei pacchetti installati su entrambi gli ambienti. Una differenza nella versione minore o patch — la causa più probabile della divergenza. Strumenti come npm ls, pip freeze, mvn dependency:tree aiuteranno a identificare rapidamente le incongruenze.
Terzo passo — riprodurre l’ambiente di produzione localmente. Utilizzate Docker Compose o strumenti simili per creare una copia esatta dell’infrastruttura di produzione. Se il bug si riproduce in un contenitore locale — il problema è nel codice, non nell’ambiente. Se non si riproduce — cercate una differenza nella configurazione.
Quarto passo — verificare i feature flag e i test A/B. È possibile che in prod il codice funzioni in una modalità diversa perché è attivato il flag sbagliato. Secondo il LaunchDarkly State of Feature Management 2023, fino al 40% dei comportamenti inaspettati in prod è correlato a valori errati dei feature flag. Un manifesto unificato dei flag per tutti gli ambienti risolve questo problema.
Lo strumento principale di prevenzione — Infrastructure as Code (IaC). Tutti gli ambienti devono essere descritti nel codice: Dockerfile, docker-compose.yml, script Terraform o playbook Ansible. Le modifiche manuali sul server sono vietate — qualsiasi modifica della configurazione passa attraverso il repository e il code review. Questo garantisce che tutti gli ambienti abbiano la stessa configurazione.
Il secondo strumento per importanza — un pipeline CI/CD unificato. Lo stesso script di build, test e deploy deve essere utilizzato per tutti gli ambienti. La differenza — solo nelle variabili target (URL, chiavi). Se il pipeline per staging e produzione differisce nei passaggi — le divergenze sono inevitabili.
Il terzo strumento — la sincronizzazione automatica dei dati. Regolarmente (una volta al giorno o secondo programma) aggiornate lo staging con una copia anonimizzata del database di produzione. Questo permette di testare il codice su dati reali anziché su fixture sintetiche. Strumenti: pg_dump/pg_restore per PostgreSQL, mysqldump per MySQL, servizi specializzati come DataGrip.
Il quarto — il monitoraggio delle divergenze. Impostate avvisi quando vengono rilevate differenze tra staging e produzione. Un semplice script che confronta gli hash dei file di configurazione o le versioni dei pacchetti installati farà risparmiare ore di debug. La prevenzione è sempre più economica della diagnosi: prevenire la divergenza degli ambienti richiede meno sforzo che cercare la causa di un bug “funziona in prod”.
Domande frequenti
Nel primo caso il bug è visibile sullo staging ma non in prod. Nel secondo — il bug è visibile a tutti tranne che allo sviluppatore il cui codice funziona localmente. Radice comune — nella divergenza degli ambienti, ma la situazione si manifesta in fasi diverse.
Mostrate che il bug sullo staging è un bug che è già pronto per passare in produzione con il prossimo deploy. Correggerlo ora costerà meno di un hotfix sotto la pressione degli utenti. Portate esempi dalla storia del progetto.
Secondo i dati di DORA 2023, circa il 25–30% degli incidenti in prod è causato da differenze tra gli ambienti. Nei team senza containerizzazione questo indicatore raggiunge il 50%. La containerizzazione lo riduce al 10–15%.
Sì, è una delle cause frequenti. In prod sono attivi CDN, Varnish o cache Redis, mentre sullo staging no. Se il bug è legato alla distribuzione di dati memorizzati nella cache, si manifesterà sullo staging e sarà nascosto dalla cache in prod.
Docker garantisce l’identità dell’ambiente in tutte le fasi: sviluppo, test, staging, produzione. Se l’immagine viene costruita una volta e utilizzata ovunque — la divergenza di versioni e configurazioni è esclusa. Un’immagine unificata — la base della riproducibilità del deploy.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche