„Pe prod funcționează” — frază pe care un programator o spune atunci când bug-ul nu se reproduce în producție, deși pe staging sau pe mașina locală eroarea se manifestă stabil. Problema este aproape întotdeauna cauzată de divergența mediilor: versiuni diferite ale dependințelor, fișiere de configurare, starea bazei de date sau setările serverului. Conform analizei Stack Overflow Developer Survey 2024, 43% dintre programatori se confruntă cel puțin o dată pe lună cu situația în care codul funcționează pe mașina locală, dar cade în producție. Analizăm de ce apare această divergență și cum să o prevenim.
Principalele puncte
„Pe prod funcționează” — este o expresie consacrată în mediul programatorilor, care desemnează situația în care codul funcționează pe serverul de producție, dar refuză să funcționeze în mediul de test sau pe mașina locală a colegului. Extern, sună ca „nu există problemă”, deși în realitate problema există — pur și simplu nu se reproduce în mediul de producție. Rădăcina divergenței constă în diferența de configurații, versiuni și date între medii.
Expresia s-a născut ca opusul altei scuze cunoscute — „La mine local funcționează”. Dacă programatorul spune „local funcționează”, înseamnă că bug-ul există doar la alții. Iar dacă „pe prod funcționează” — bug-ul există doar pe staging sau în mediul de test, dar producția este curată. Ironia sorții: în ambele cazuri problema este reală, doar că se manifestă la altcineva decât cel care privește. Conform cercetării DevOps Research and Assessment (DORA) 2023, echipele cu un nivel ridicat de automatizare a implementării se confruntă cu astfel de divergențe de 3 ori mai rar.
Din punctul de vedere al afacerii, situația „pe prod funcționează” este mai periculoasă decât pare. Dacă bug-ul este pe staging, dar nu în producție, programatorul îl poate ignora — și atunci la următoarea implementare eroarea va ajunge în producție. Ușurarea temporară se transformă într-o problemă viitoare care va trebui rezolvată sub presiunea utilizatorilor.
Cauza psihologică a persistenței acestei fraze — reflexul defensiv. Programatorul care vede bug-ul pe staging, dar nu în producție, poate subconștient minimaliza problema: „dacă în producție totul este bine, atunci nu este urgent”. O prejudecată cognitivă clasică — eroarea supraviețuitorului, unde succesul vizibil al producției cântărește mai mult decât amenințarea potențială a unei viitoare defecțiuni.
A doua cauză — responsabilitatea difuză. Dacă producția funcționează, dar staging-ul nu, vinovatul este mediul, nu codul. Programatorul își îndepărtează responsabilitatea pentru bug, transferând-o inginerului DevOps sau administratorului. Conform Atlassian State of DevOps 2022, în echipele fără un mediu unificat de implementare (Docker, Kubernetes) astfel de transferuri de responsabilitate au loc cu 60% mai des.
A treia cauză — teama de lansare cu zero downtime. Dacă programatorul repară bug-ul pe staging și implementează corecția, aceasta va necesita un nou code review, testare și deploy. Fraza „pe prod funcționează” permite amânarea corecției până la următoarea lansare, reducând sarcina curentă. Corecția amânată — una dintre principalele cauze ale acumulării datoriei tehnice în echipe.
Producția și staging-ul nu sunt niciodată complet identice — acest lucru este imposibil tehnic din cauza diferențelor de scară, încărcare și date. Cu toate acestea, parametrii cheie trebuie să coincidă: versiunea sistemului de operare, a compilatorului, interpretorului, bazei de date, serverului web și a tuturor dependințelor proiectului. Dacă cel puțin un parametru diferă — comportamentul codului se poate schimba.
Principalele diferențe între medii includ:
Containerizarea rezolvă majoritatea acestor probleme. Imaginea Docker construită pentru producție trebuie utilizată și pe staging. Singura diferență — variabilele de mediu și montarea volumelor. Conform Docker State of Application Development 2023, echipele care utilizează o imagine unică pentru toate mediile reduc numărul de divergențe cu 74%.
| Parametru | Mediul local | Staging | Producție |
|---|---|---|---|
| OS | macOS / Windows | Server Linux | Server Linux |
| Bază de date | SQLite / MySQL local | Cluster MySQL | Cluster MySQL cu replicare |
| Încărcare | 1 utilizator | Simulare 10–100 | 1000+ reali |
| Date | Fixture | Mascate | Reale |
| CDN / cache | Nu | Parțial | Complet |
Prima și cea mai frecventă cauză — versiuni diferite ale dependințelor. Programatorul instalează un pachet local cu flag-ul --save, dar uită să actualizeze package.json sau fișierul lock. La implementarea în producție se instalează o altă versiune care se comportă diferit. Pentru ecosistemul npm, fișierul lock rezolvă complet problema, pentru ceilalți manageri de pachete — mecanisme analoge (Gemfile.lock, Podfile.lock, pubspec.lock).
A doua cauză — variabile de mediu lipsă sau în plus. Programatorul folosește fișierul .env pe mașina locală, dar nu adaugă variabilele corespunzătoare în pipeline-ul CI/CD sau pe server. Rezultatul — codul cade cu eroare de conectare la API sau baza de date. Conform GitLab DevSecOps Survey 2023, 27% dintre incidentele din producție sunt legate de variabile de mediu incorecte.
A treia cauză — starea bazei de date. Pe staging, baza de date poate conține înregistrări care nu există în producție, sau invers — lipsesc migrările. Scenariu tipic: programatorul scrie cod care lucrează cu un câmp nou din tabel, dar migrarea nu a fost încă aplicată în producție. Strategia de migrare cu compatibilitate inversă — singurul mod de a evita astfel de situații.
A patra cauză — setările regionale și lingvistice. Formatarea datelor, separatoarele numerelor fracționare, codificarea textului — toate acestea pot diferi pe mașina locală a programatorului și pe server. Deosebit de relevant pentru proiecte cu internaționalizare. Soluția — specificarea explicită a locale în configurația aplicației și a nu se baza pe setările de sistem.
Primul pas — compararea logurilor ambelor medii. Diferența în nivelul de logare ascunde adesea cauza: în producție poate fi activat INFO, iar pe staging DEBUG. Configurați același nivel de logare și asigurați-vă că ambele medii scriu într-un format care permite compararea automată. Utilizați sisteme centralizate de colectare a logurilor — Sentry, Datadog, ELK Stack.
Al doilea pas — verificarea versiunilor dependințelor. Comparați fișierele lock, afișați lista pachetelor instalate pe ambele medii. Diferența în versiunea minor sau patch — cea mai probabilă cauză a divergenței. Instrumente precum npm ls, pip freeze, mvn dependency:tree ajută la identificarea rapidă a nepotrivirilor.
Al treilea pas — reproducerea mediului de producție local. Utilizați Docker Compose sau instrumente similare pentru a ridica o copie exactă a infrastructurii de producție. Dacă bug-ul se reproduce în containerul local — problema este în cod, nu în mediu. Dacă nu se reproduce — căutați diferența în configurație.
Al patrulea pas — verificarea feature flags și a testelor A/B. Poate că în producție codul funcționează într-un mod diferit pentru că este activat un alt flag. Conform LaunchDarkly State of Feature Management 2023, până la 40% din comportamentul neașteptat în producție este legat de valori incorecte ale feature flags. Manifestul unic al flag-urilor pentru toate mediile rezolvă această problemă.
Instrumentul principal de prevenire — Infrastructure as Code (IaC). Toate mediile trebuie descrise în cod: Dockerfile, docker-compose.yml, scripturi Terraform sau playbook-uri Ansible. Modificările manuale pe server sunt interzise — orice schimbare de configurație trece prin repository și code review. Aceasta garantează că toate mediile au aceeași configurație.
Al doilea instrument ca importanță — pipeline-ul CI/CD unificat. Același script de build, testare și deploy trebuie utilizat pentru toate mediile. Diferența este doar în variabilele țintă (URL, chei). Dacă pipeline-ul pentru staging și producție diferă prin pași — divergențele sunt inevitabile.
Al treilea instrument — sincronizarea automată a datelor. Actualizați regulat (o dată pe zi sau conform programului) staging-ul cu o copie anonimizată a bazei de date de producție. Acest lucru permite testarea codului pe date reale, nu pe fixture sintetice. Instrumente: pg_dump/pg_restore pentru PostgreSQL, mysqldump pentru MySQL, servicii specializate precum DataGrip.
Al patrulea — monitorizarea divergențelor. Configurați notificări la detectarea diferențelor între staging și producție. Un script simplu care compară hash-urile fișierelor de configurare sau versiunile pachetelor instalate va economisi ore de depanare. Prevenția este întotdeauna mai ieftină decât diagnosticarea: prevenirea divergențelor mediilor necesită mai puțin efort decât căutarea cauzei bug-ului „pe prod funcționează”.
Întrebări frecvente
În primul caz, bug-ul este vizibil pe staging, dar nu în producție. În al doilea — bug-ul este văzut de toți, cu excepția programatorului la care codul funcționează local. Rădăcina comună — în divergența mediilor, dar situația se manifestă în etape diferite.
Arătați că bug-ul de pe staging este un bug care este deja gata să ajungă în producție cu următoarea implementare. Repararea acum va costa mai puțin decât un hotfix sub presiunea utilizatorilor. Dați exemple din istoricul proiectului.
Conform DORA 2023, aproximativ 25–30% din incidentele din producție sunt cauzate de diferențele între medii. În echipele fără containerizare, acest indicator atinge 50%. Containerizarea îl reduce la 10–15%.
Da, aceasta este una dintre cauzele frecvente. În producție este activat CDN, Varnish sau cache Redis, iar pe staging — nu. Dacă bug-ul este legat de livrarea datelor din cache, pe staging se va manifesta, iar în producție va fi ascuns de cache.
Docker garantează identitatea mediului în toate etapele: dezvoltare, testare, staging, producție. Dacă imaginea este construită o dată și utilizată peste tot — divergența versiunilor și configurațiilor este exclusă. Imaginea unică este baza repetabilității implementării.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și