Ради на мојој машини: шта је, зашто се дешава и како превенирати

Аутор: IT Sectr Објављено: 2026-07-30 Време читања: 8 мин

„Ради на мојој машини” (енгл. „Works on my machine”) — класична фраза програмера који не може да репродукује грешку у свом локалном окружењу, иако се грешка стабилно појављује код других чланова тима или у продукцији. Ситуација настаје због разлика у конфигурацији, верзијама зависности, оперативном систему или подацима између машине програмера и окружења у којем се грешка репродукује. Према Stack Overflow Survey 2023, 58% програмера бар једном месечно изговарају ову фразу, а 31% — недељно. Разумевамо зашто код не ради свуда једнако и како стандардизовати окружење.

Главно

  • „Works on my machine” — мем и реалан проблем који указује на разилажење окружења у тиму
  • Основни узроци: различите верзије зависности, промењиве окружења, ОС и регионалне поставке
  • Проблем се решава стандардизацијом окружења путем Docker-а или Vagrant-а
  • Lock-датотеке (package-lock, Podfile.lock) фиксирају верзије зависности за све програмере
  • Редовна синхронизација са репозиторијумом и чиста инсталација зависности смањују учесталост проблема

Шта значи „Ради на мојој машини”

„Ради на мојој машини” — фраза коју програмер изговара када колега или тестер пријави грешку, а на машини програмера се та грешка не репродукује. Споља изгледа као негирање проблема, али технички је ситуација реална: код заиста може да ради у једном окружењу и пада у другом. Разлика у једном биту конфигурације — и понашање апликације се коренито мења.

Фраза је постала мем у IT заједници јер је истовремено истинита и бескорисна. Са становишта програмера — код заиста ради на његовој машини. Са становишта тима — проблем постоји и мора да се реши, а не да се оправдава. Хумор ситуације је у томе што програмер говори истину, али та истина не помаже да се поправи грешка. Мем је толико популаран да су му посвећене хиљаде објава на Reddit, XKCD и DevOps конференцијама.

Са становишта процеса, фраза „ради на мојој машини” је индикатор проблема са репродуктибилношћу окружења. Ако два програмера не могу да добију исти резултат на истом коду — значи да процес подешавања окружења није стандардизован. DevOps пракса тврди: окружење мора да буде репродуктибилно једном наредбом из репозиторијума без ручних радњи.

Зашто се локално окружење разликује од продукције

Локално окружење програмера скоро увијек се разликује од продукције. Програмер користи macOS или Windows, док сервер ради на Linux-у. Различити оперативни системи имају различите датотечне системе, кодне странице, тајминг нити и системске позиве. Чак и ако су оба окружења Linux — верзија језгра, glibc, OpenSSL могу да се разликују.

Други разлог — скуп инсталираног софтвера. На машини програмера може бити инсталирана глобална верзија Node.js 20, а у CI/CD конфигурацији је наведена верзија 18. Или програмер локално користи PostgreSQL 16, а на продукцији — PostgreSQL 14. Разлике у малим верзијама често нису приметне, али велике надоградње могу да промене понашање SQL упита. Према npm Inc., 67% грешака везаних за зависности проузроковано је разликом у patch верзијама.

Трећи разлог — мрежни услови. На локалној машини нема кашњења, ограничења протока и проблема са DNS-ом. У продукцији, сваки захтев ка спољашњем API-ју може да траје 500 ms уместо 5 ms. Тајмаути, retry логика, race conditions — сви ови проблеми се појављују само под реалним оптерећењем и у реалним мрежним условима. Емулација мреже путем алата као што је Toxiproxy помаже да се открију ови проблеми пре деплоја.

Типични узроци нерепродуковања грешке локално

Први разлог — недостатак података. Програмер ради са тест фиксурама, а у продукцији су милиони записа са неочекиваним вредностима. NULL у пољу који је програмер сматрао обавезним, Unicode знак у имену, превише дуг низ — све то може да изазове грешке које су нерепродуктивне на локалној бази са синтетичким подацима.

Други разлог — различити флегови компилације и изградње. Релеазна верзија (Release/Distribution) се може разликовати од дебажне (Debug). Оптимизације компилатора, уклањање debug логова, инлајнирање функција — све то може да сакрије или, напротив, изазове грешке. Типичан примјер: у дебажној верзији ради assert који пада у релеазној због другачијег редоследа иницијализације промењивих.

Трећи разлог — локални кеш и привремене датотеке. Програмер може да не примети грешку јер су у прегледачу кеширани стари скриптови, у Redis-у су сачувани застарели подаци, а у датотечном систему висе привремене датотеке од претходних покретања. Чисто покретање (incognito начин, брисање кеша, свежа инсталација) често репродукује грешку која се није појављивала „сама од себе”.

Четврти разлог — сукоби глобалних и локалних зависности. Алати као што су Ruby gems, Python pip, Node.js npm могу имати глобално инсталиране пакете који помажу коду да ради локално, али недостају у продукцији. Коришћење виртуелних окружења (virtualenv, venv, nvm) изолише пројекат од глобалних инсталација и чини окружење поновљивим.

Утицај на тимски рад и поверење

Фраза „ради на мојој машини” уништава поверење у тиму. Ако програмер редовно не може да репродукује грешке, колеге почињу да сумњају у његову компетентност или пажљивост тестирања. Током времена, то доводи до микроменаџмента: сваку измену треба да провери други програмер, што успорава развој. Према Google Project Aristotle, психолошка сигурност у тиму директно утиче на продуктивност, а сталне расправе око окружења су један од фактора њеног смањења.

Други проблем — успоравање code review-а. Ако програмер не може да репродукује грешку локално, може да одбије pull request колеге речима „код мене ради — значи проблем је код тебе”. То изазива сукобе и одлага испоруку функционалности. Стандардизација окружења уклања овај сукоб: ако оба програмера раде у истом Docker контејнеру, питање „код кога ради” губи смисао.

Трећи проблем — губитак грешака у трекеру. Грешке које се „не репродукују код програмера” често се затварају са напоменом „не може се репродуковати” (Cannot Reproduce). Након месец дана, грешка се појављује у продукцији, и њено поправљање кошта 10 пута више. Правило: ако се грешка репродукује бар код једне особе — она постоји, без обзира да ли ради код програмера или не.

Како стандардизовати окружење програмера

Први и најефикаснији начин — Docker. Цео пројекат треба да се покреће кроз docker-compose up без додатних радњи. База података, кеш, ред порука, веб сервер — све се подиже у контејнерима. Програмер инсталира само Docker и Git. Остало — унутар контејнера. То гарантује да сви чланови тима имају исто окружење без обзира на ОС.

Други начин — менаџери верзија. Ако Docker није могућ (/ mиценциона ограничења, legacy инфраструктура), користите nvm (Node.js), rbenv (Ruby), pyenv (Python), sdkman (Java). Менаџери верзија омогућавају пребацивање између верзија језика и алата у оквиру пројекта. Датотеке .nvmrc, .ruby-version, .python-version треба да буду у репозиторијуму и проверавати од стране CI/CD.

Трећи начин — Vagrant за виртуелне машине. Vagrant подиже виртуелну машину са задатим ОС и конфигурацијом изнад VirtualBox или VMware. Унутар VM се инсталирају све зависности путем provisioning скрипти (shell, Ansible, Puppet). Vagrant је тежи од Docker-а, али пружа потпуну изолацију на нивоу ОС — корисно за пројекте који зависе од одређене верзије линукс језгра.

Четврти — makefile и bootstrap скрипте. Чак и једноставан Makefile са циљевима install, test, build, clean може да стандардизује рутинске радње. Наредба make install треба да инсталира све зависности, подеси базу и креира тест податке. Јединствена тачка уласка за све програмере искључује ручне грешке при подешавању окружења.

Алати за превенцију разилажења окружења

Основни алат — lock-датотеке зависности. package-lock.json (npm), yarn.lock (Yarn), Podfile.lock (CocoaPods), pubspec.lock (Flutter) фиксирају тачне верзије сваког пакета. Без lock-датотеке, два програмера која инсталирају зависности у различито време могу добити различите мале верзије. Lock-датотека треба да буде у репозиторијуму и да се не уређује ручно.

Други алат — .env.example у репозиторијуму. Шаблон промењивих окружења са коментарима. Програмер га копира у .env и попуњава сопствене вредности. CI/CD пајплајн проверава да су све обавезне промењиве постављене. Према GitLab 2023, тимови који користе .env.example смањују број инцидената везаних за промењиве окружења за 40%.

Трећи алат — pre-commit хукови. Аутоматска провера која се покреће пре сваког commit-а: линтер, форматер, провера типова, тестови. Ако су хукови исто подешени код свих програмера, грешке форматирања или типова које су „прошле на локалној машини” неће стићи до продукције. Husky за JavaScript и pre-commit за Python су популарна решења.

Четврти — CI/CD пајплајн који покреће тестове у чистом окружењу. Ако тестови пролазе у CI, али не локално — проблем је у подешавању локалног окружења. Ако тестови не пролазе у CI — pull request се не мерџује. Ово чврсто правило искључује продирање грешака који „раде локално” у главну грану.

Често постављана питања

Зашто програмери често кажу „код мене ради” уместо да одмах траже узрок?

То је одбранбена реакција: програмер троши пуно времена на отклањање, и чути да код не ради је психолошки болно. Фраза даје време да се „пребаци” и почне трагати узрок без осећаја кривице.

Како реаговати ако програмер каже „код мене ради”?

Замолите га да репродукује грешку у чистом окружењу (clean install, incognito начин). Ако се не репродукује — упоредите верзије зависности и промењиве окружења. Ако не помаже — подигните Docker окружење идентично продукцији.

Како Docker решава проблем „Works on my machine”?

Docker пружа изолован контејнер са фиксираном конфигурацијом који једнако ради на сваком ОС. Сви програмери користе исти Dockerfile, па је окружење идентично. Ако се грешка не репродукује у контејнеру — значи да је проблем заиста у коду, а не у систему.

Како lock-датотеке помажу да се избегну разилажења?

Lock-датотека фиксира тачне хешеве и верзије свих транзитивних зависности. Чак и ако се у регистру пакета појави нова верзија зависности, инсталација по lock-датотеци гарантује да ће сваки програмер добити исти скуп пакета као и остали.

Исплати ли се користити виртуелне машине уместо Docker-а?

Vagrant са VirtualBox је оправдан ако пројекат зависи од специфичних модула језгра ОС или захтева потпуну изолацију на нивоу језгра. За 90% пројеката Docker је лакши, бржи и практичнији. Избор зависи од тога колико дубоко пројекат интерагује са ОС.

Закључак

  • „Ради на мојој машини” — није изговор, већ симптом разилажења окружења у тиму
  • Основни узроци: различите верзије зависности и алата, промењиве окружења, ОС и подаци
  • Фраза уништава поверење у тиму и успорава code review и испоруку функционалности
  • Docker — главни алат стандардизације окружења за све програмере
  • Lock-датотеке и .env.example фиксирају конфигурацију у репозиторијуму
  • Pre-commit хукови и CI/CD пајплајн аутоматски проверавају код у чистом окружењу
  • Стандардизовано окружење штеди сате отклањања и елиминише „магичне” грешке

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође