“Στο prod δουλεύει” — φράση που λέει ένας προγραμματιστής όταν το bug δεν αναπαράγεται στην παραγωγή, αν και στο staging ή στο τοπικό μηχάνημα το σφάλμα εμφανίζεται σταθερά. Το πρόβλημα σχεδόν πάντα προκαλείται από απόκλιση περιβαλλόντων: διαφορετικές εκδόσεις εξαρτήσεων, αρχεία διαμόρφωσης, κατάσταση βάσης δεδομένων ή ρυθμίσεις διακομιστή. Σύμφωνα με την ανάλυση του Stack Overflow Developer Survey 2024, το 43% των προγραμματιστών αντιμετωπίζει τουλάχιστον μία φορά το μήνα την κατάσταση όπου ο κώδικας λειτουργεί στο τοπικό μηχάνημα αλλά πέφτει στην παραγωγή. Εξετάζουμε γιατί προκύπτει αυτή η απόκλιση και πώς να την αποτρέψουμε.
Κύρια σημεία
“Στο prod δουλεύει” — αυτή είναι μια καθιερωμένη έκφραση στην κοινότητα των προγραμματιστών που περιγράφει μια κατάσταση όπου ο κώδικας λειτουργεί στον διακομιστή παραγωγής αλλά αρνείται να λειτουργήσει στο περιβάλλον δοκιμών ή στο τοπικό μηχάνημα ενός συναδέλφου. Εξωτερικά ακούγεται σαν “δεν υπάρχει πρόβλημα”, αν και στην πραγματικότητα το πρόβλημα υπάρχει — απλά δεν αναπαράγεται στο περιβάλλον παραγωγής. Η ρίζα της απόκλισης βρίσκεται στη διαφορά διαμορφώσεων, εκδόσεων και δεδομένων μεταξύ των περιβαλλόντων.
Η φράση γεννήθηκε ως αντίποδας μιας άλλης γνωστής δικαιολογίας — “Σε μένα τοπικά δουλεύει”. Αν ο προγραμματιστής λέει “τοπικά δουλεύει”, σημαίνει ότι το bug υπάρχει μόνο σε άλλους. Και αν “στο prod δουλεύει” — το bug υπάρχει μόνο στο staging ή στο περιβάλλον δοκιμών, αλλά η παραγωγή είναι καθαρή. Ειρωνεία της τύχης: και στις δύο περιπτώσεις το πρόβλημα είναι πραγματικό, απλά εκδηλώνεται σε κάποιον άλλον εκτός από αυτόν που κοιτάζει. Σύμφωνα με την έρευνα DevOps Research and Assessment (DORA) 2023, οι ομάδες με υψηλό επίπεδο αυτοματοποίησης ανάπτυξης αντιμετωπίζουν τέτοιες αποκλίσεις 3 φορές λιγότερο συχνά.
Από επιχειρηματική σκοπιά, η κατάσταση “στο prod δουλεύει” είναι πιο επικίνδυνη από όσο φαίνεται. Αν το bug υπάρχει στο staging αλλά όχι στην παραγωγή, ο προγραμματιστής μπορεί να το αγνοήσει — και τότε στην επόμενη ανάπτυξη το σφάλμα θα μεταφερθεί στην παραγωγή. Προσωρινή ανακούφιση μετατρέπεται σε μελλοντικό πρόβλημα που θα πρέπει να διορθωθεί υπό την πίεση των χρηστών.
Ο ψυχολογικός λόγος επιμονής αυτής της φράσης — αμυντικό αντανακλαστικό. Ένας προγραμματιστής που βλέπει το bug στο staging αλλά όχι στην παραγωγή, μπορεί υποσυνείδητα να υποβαθμίζει το πρόβλημα: “αν στην παραγωγή όλα είναι καλά, τότε δεν είναι επείγον”. Μια κλασική γνωστική προκατάληψη — το σφάλμα επιζώντος, όπου η ορατή επιτυχία της παραγωγής υπερισχύει της πιθανής απειλής μελλοντικής βλάβης.
Ο δεύτερος λόγος — θολή ευθύνη. Αν η παραγωγή λειτουργεί και το staging όχι, ένοχος είναι το περιβάλλον, όχι ο κώδικας. Ο προγραμματιστής αποποιείται την ευθύνη για το bug, μεταφέροντάς την στον μηχανικό DevOps ή στον διαχειριστή. Σύμφωνα με το Atlassian State of DevOps 2022, σε ομάδες χωρίς ενοποιημένο περιβάλλον ανάπτυξης (Docker, Kubernetes) τέτοιες μεταφορές ευθύνης συμβαίνουν 60% συχνότερα.
Ο τρίτος λόγος — φόβος για έκδοση με μηδενικό χρόνο διακοπής. Αν ο προγραμματιστής διορθώσει το bug στο staging και κυκλοφορήσει τη διόρθωση, αυτό θα απαιτήσει εκ νέου code review, δοκιμές και deploy. Η φράση “στο prod δουλεύει” επιτρέπει την αναβολή της διόρθωσης μέχρι την επόμενη έκδοση, μειώνοντας το τρέχον φορτίο. Αναβληθείσα διόρθωση — μία από τις κύριες αιτίες συσσώρευσης τεχνικού χρέους σε ομάδες.
Παραγωγή και staging δεν είναι ποτέ εντελώς πανομοιότυπα — αυτό είναι τεχνικά αδύνατο λόγω διαφορών σε κλίμακα, φορτίο και δεδομένα. Ωστόσο, οι βασικές παράμετροι πρέπει να συμπίπτουν: η έκδοση του λειτουργικού συστήματος, του compiler, του interpreter, της βάσης δεδομένων, του web server και όλων των εξαρτήσεων του έργου. Αν τουλάχιστον μία παράμετρος διαφέρει — η συμπεριφορά του κώδικα μπορεί να αλλάξει.
Οι κύριες διαφορές μεταξύ των περιβαλλόντων περιλαμβάνουν:
Containerization λύνει τα περισσότερα από αυτά τα προβλήματα. Η εικόνα Docker που δημιουργήθηκε για παραγωγή πρέπει να χρησιμοποιείται και στο staging. Η μόνη διαφορά — μεταβλητές περιβάλλοντος και προσαρτήσεις τόμου. Σύμφωνα με το Docker State of Application Development 2023, οι ομάδες που χρησιμοποιούν μία ενιαία εικόνα για όλα τα περιβάλλοντα μειώνουν τον αριθμό αποκλίσεων κατά 74%.
| Παράμετρος | Τοπικό περιβάλλον | Staging | Παραγωγή |
|---|---|---|---|
| ΛΣ | macOS / Windows | Linux server | Linux server |
| Βάση δεδομένων | SQLite / τοπική MySQL | MySQL cluster | MySQL cluster με αντιγραφή |
| Φορτίο | 1 χρήστης | Προσομοίωση 10–100 | 1000+ πραγματικοί |
| Δεδομένα | Fixture | Αποκρυμμένα | Πραγματικά |
| CDN / cache | Κανένα | Μερικώς | Πλήρως |
Η πρώτη και συχνότερη αιτία — διαφορετικές εκδόσεις εξαρτήσεων. Ο προγραμματιστής εγκαθιστά ένα πακέτο τοπικά με τη σημαία --save, αλλά ξεχνά να ενημερώσει το package.json ή το lock αρχείο. Κατά την ανάπτυξη στην παραγωγή εγκαθίσταται μια άλλη έκδοση που συμπεριφέρεται διαφορετικά. Για το οικοσύστημα npm, το lock αρχείο λύνει πλήρως το πρόβλημα, για άλλους διαχειριστές πακέτων — ανάλογοι μηχανισμοί (Gemfile.lock, Podfile.lock, pubspec.lock).
Η δεύτερη αιτία — ελλείπουσες ή πλεονάζουσες μεταβλητές περιβάλλοντος. Ο προγραμματιστής χρησιμοποιεί αρχείο .env στο τοπικό μηχάνημα, αλλά δεν προσθέτει τις αντίστοιχες μεταβλητές στο pipeline CI/CD ή στον διακομιστή. Αποτέλεσμα — ο κώδικας καταρρέει με σφάλμα σύνδεσης στο API ή στη βάση δεδομένων. Σύμφωνα με το GitLab DevSecOps Survey 2023, το 27% των περιστατικών στην παραγωγή σχετίζονται με εσφαλμένες μεταβλητές περιβάλλοντος.
Η τρίτη αιτία — κατάσταση της βάσης δεδομένων. Στο staging, η βάση δεδομένων μπορεί να περιέχει εγγραφές που δεν υπάρχουν στην παραγωγή, ή αντίστροφα — να λείπουν μεταναστεύσεις. Τυπικό σενάριο: ο προγραμματιστής γράφει κώδικα που λειτουργεί με ένα νέο πεδίο σε έναν πίνακα, αλλά η μετανάστευση δεν έχει ακόμη εφαρμοστεί στην παραγωγή. Στρατηγική μετανάστευσης με αντίστροφη συμβατότητα — ο μόνος τρόπος αποφυγής τέτοιων καταστάσεων.
Η τέταρτη αιτία — περιφερειακές και γλωσσικές ρυθμίσεις. Μορφοποίηση ημερομηνιών, διαχωριστικά δεκαδικών αριθμών, κωδικοποίηση κειμένου — όλα αυτά μπορεί να διαφέρουν στο τοπικό μηχάνημα του προγραμματιστή και στον διακομιστή. Ιδιαίτερα σχετικό για έργα με διεθνοποίηση. Λύση — ρητός καθορισμός locale στη διαμόρφωση της εφαρμογής και μη εξάρτηση από τις ρυθμίσεις συστήματος.
Πρώτο βήμα — σύγκριση αρχείων καταγραφής και των δύο περιβαλλόντων. Η διαφορά στο επίπεδο καταγραφής συχνά κρύβει την αιτία: στην παραγωγή μπορεί να είναι ενεργοποιημένο το INFO, στο staging το DEBUG. Ρυθμίστε το ίδιο επίπεδο καταγραφής και βεβαιωθείτε ότι και τα δύο περιβάλλοντα γράφουν σε μορφή που επιτρέπει μηχανική σύγκριση. Χρησιμοποιήστε κεντρικοποιημένα συστήματα συλλογής καταγραφών — Sentry, Datadog, ELK Stack.
Δεύτερο βήμα — έλεγχος εκδόσεων εξαρτήσεων. Συγκρίνετε τα lock αρχεία, εμφανίστε τη λίστα εγκατεστημένων πακέτων και στα δύο περιβάλλοντα. Η διαφορά στην minor ή patch έκδοση — η πιο πιθανή αιτία απόκλισης. Εργαλεία όπως npm ls, pip freeze, mvn dependency:tree βοηθούν στον γρήγορο εντοπισμό ασυμφωνιών.
Τρίτο βήμα — αναπαραγωγή του περιβάλλοντος παραγωγής τοπικά. Χρησιμοποιήστε Docker Compose ή παρόμοια εργαλεία για να σηκώσετε ένα ακριβές αντίγραφο της υποδομής παραγωγής. Αν το bug αναπαράγεται στο τοπικό container — το πρόβλημα είναι στον κώδικα, όχι στο περιβάλλον. Αν δεν αναπαράγεται — αναζητήστε τη διαφορά στη διαμόρφωση.
Τέταρτο βήμα — έλεγχος feature flags και δοκιμών A/B. Πιθανώς στην παραγωγή ο κώδικας λειτουργεί σε διαφορετική λειτουργία επειδή είναι ενεργοποιημένη η λάθος σημαία. Σύμφωνα με το LaunchDarkly State of Feature Management 2023, έως και 40% της απροσδόκητης συμπεριφοράς στην παραγωγή σχετίζεται με εσφαλμένες τιμές feature flags. Ενιαίο μανιφέστο σημαιών για όλα τα περιβάλλοντα λύνει αυτό το πρόβλημα.
Το κύριο εργαλείο πρόληψης — Infrastructure as Code (IaC). Όλα τα περιβάλλοντα πρέπει να περιγράφονται σε κώδικα: Dockerfile, docker-compose.yml, σενάρια Terraform ή playbooks Ansible. Οι χειροκίνητες αλλαγές στον διακομιστή απαγορεύονται — κάθε αλλαγή διαμόρφωσης περνά μέσα από το αποθετήριο και code review. Αυτό εγγυάται ότι όλα τα περιβάλλοντα έχουν την ίδια διαμόρφωση.
Το δεύτερο σημαντικότερο εργαλείο — ενοποιημένο pipeline CI/CD. Το ίδιο σενάριο build, δοκιμών και deploy πρέπει να χρησιμοποιείται για όλα τα περιβάλλοντα. Η διαφορά είναι μόνο στις μεταβλητές στόχου (URL, κλειδιά). Αν το pipeline για το staging και την παραγωγή διαφέρει σε βήματα — οι αποκλίσεις είναι αναπόφευκτες.
Το τρίτο εργαλείο — αυτόματος συγχρονισμός δεδομένων. Ενημερώνετε τακτικά (μία φορά την ημέρα ή σύμφωνα με πρόγραμμα) το staging με ένα ανωνυμοποιημένο αντίγραφο της βάσης δεδομένων παραγωγής. Αυτό επιτρέπει τη δοκιμή κώδικα σε πραγματικά δεδομένα, όχι σε συνθετικά fixture. Εργαλεία: pg_dump/pg_restore για PostgreSQL, mysqldump για MySQL, εξειδικευμένες υπηρεσίες όπως DataGrip.
Τέταρτο — παρακολούθηση αποκλίσεων. Ρυθμίστε ειδοποιήσεις κατά τον εντοπισμό διαφορών μεταξύ staging και παραγωγής. Ένα απλό σενάριο που συγκρίνει hashes αρχείων διαμόρφωσης ή εκδόσεις εγκατεστημένων πακέτων θα εξοικονομήσει ώρες εντοπισμού σφαλμάτων. Η πρόληψη είναι πάντα φθηνότερη από τη διάγνωση: η αποτροπή αποκλίσεων περιβαλλόντων απαιτεί λιγότερη προσπάθεια από την αναζήτηση της αιτίας του bug “στο prod δουλεύει”.
Συχνές ερωτήσεις
Στην πρώτη περίπτωση, το bug είναι ορατό στο staging αλλά όχι στην παραγωγή. Στη δεύτερη — το βλέπουν όλοι εκτός από τον προγραμματιστή του οποίου ο κώδικας λειτουργεί τοπικά. Κοινή ρίζα — στην απόκλιση περιβαλλόντων, αλλά η κατάσταση εκδηλώνεται σε διαφορετικά στάδια.
Δείξτε ότι το bug στο staging είναι ένα bug που είναι ήδη έτοιμο να μεταφερθεί στην παραγωγή με την επόμενη ανάπτυξη. Η διόρθωση τώρα θα κοστίσει λιγότερο από ένα hotfix υπό την πίεση των χρηστών. Δώστε παραδείγματα από την ιστορία του έργου.
Σύμφωνα με το DORA 2023, περίπου 25–30% των περιστατικών στην παραγωγή προκαλούνται από διαφορές μεταξύ περιβαλλόντων. Σε ομάδες χωρίς containerization, το ποσοστό αυτό φτάνει το 50%. Το containerization το μειώνει στο 10–15%.
Ναι, αυτή είναι μία από τις συχνές αιτίες. Στην παραγωγή είναι ενεργοποιημένο το CDN, Varnish ή Redis cache, ενώ στο staging όχι. Αν το bug σχετίζεται με την παράδοση προσωρινά αποθηκευμένων δεδομένων, στο staging θα εμφανιστεί, ενώ στην παραγωγή θα κρυφτεί από την προσωρινή μνήμη.
Το Docker εγγυάται την ταυτότητα του περιβάλλοντος σε όλα τα στάδια: ανάπτυξη, δοκιμές, staging, παραγωγή. Αν η εικόνα δημιουργηθεί μία φορά και χρησιμοποιείται παντού — η απόκλιση εκδόσεων και διαμορφώσεων αποκλείεται. Η ενιαία εικόνα είναι η βάση της αναπαραγωγιμότητας της ανάπτυξης.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης