«На проде работает» — фраза, которую разработчик говорит, когда баг не воспроизводится на продакшене, хотя на стейджинге или локальной машине ошибка стабильно проявляется. Проблема почти всегда вызвана расхождением окружений: разные версии зависимостей, конфигурационные файлы, состояние базы данных или настройки сервера. По данным анализа Stack Overflow Developer Survey 2024, 43% разработчиков хотя бы раз в месяц сталкиваются с ситуацией, когда код работает на локальной машине, но падает на продакшене. Разбираемся, почему возникает это расхождение и как его предотвратить.
Главное
«На проде работает» — это устойчивое выражение в среде разработчиков, обозначающее ситуацию, когда код функционирует на продакшен-сервере, но отказывается работать на тестовом окружении или локальной машине коллеги. Внешне это звучит как «проблемы нет», хотя на самом деле проблема есть — просто она не воспроизводится в продакшен-среде. Корень расхождения — в различии конфигураций, версий и данных между окружениями.
Фраза родилась как антипод другой известной отговорки — «У меня локально работает». Если разработчик говорит «локально работает», значит баг есть только у других. А если «на проде работает» — баг есть только на стейджинге или тестовой среде, но продакшен чист. Ирония судьбы: в обоих случаях проблема реальна, просто она проявляется не у того, кто смотрит. По данным исследования DevOps Research and Assessment (DORA) 2023, команды с высоким уровнем автоматизации развёртывания сталкиваются с такими расхождениями в 3 раза реже.
С точки зрения бизнеса, ситуация «на проде работает» опаснее, чем кажется. Если баг есть на стейджинге, но не на проде, разработчик может проигнорировать его — и тогда при следующем деплое ошибка уйдёт в продакшен. Временное облегчение оборачивается будущей проблемой, которую придётся фиксить под давлением пользователей.
Психологическая причина устойчивости фразы — защитный рефлекс. Разработчик, который видит баг на стейджинге, но не на проде, может подсознательно обесценивать проблему: «раз в продакшене всё хорошо, значит это не срочно». Классический cognitive bias — ошибка выжившего, где видимый успех продакшена перевешивает потенциальную угрозу будущего сбоя.
Вторая причина — размытая ответственность. Если продакшен работает, а стейджинг нет, виноватым оказывается окружение, а не код. Разработчик снимает с себя ответственность за баг, перекладывая её на DevOps-инженера или админа. По данным Atlassian State of DevOps 2022, в командах без единой среды развёртывания (Docker, Kubernetes) такие перекладывания происходят на 60% чаще.
Третья причина — страх перед релизом с нулевым downtime. Если разработчик зафиксит баг на стейджинге и выкатит исправление, это потребует повторного code review, тестирования и деплоя. Фраза «на проде работает» позволяет отложить исправление до следующего релиза, снижая текущую нагрузку. Отложенный фикс — одна из главных причин накопления технического долга в командах.
Продакшен и стейджинг никогда не бывают полностью идентичными — это технически невозможно из-за разницы в масштабе, нагрузке и данных. Однако ключевые параметры должны совпадать: версия операционной системы, компилятора, интерпретатора, базы данных, веб-сервера и всех зависимостей проекта. Если хотя бы один параметр отличается — поведение кода может измениться.
Основные различия между окружениями включают:
Контейнеризация решает большую часть этих проблем. Docker-образ, собранный для продакшена, должен использоваться и на стейджинге. Единственное отличие — переменные окружения и volume-монтирования. По данным Docker State of Application Development 2023, команды, использующие единый образ для всех окружений, сокращают количество расхождений на 74%.
| Параметр | Локальная среда | Стейжинг | Продакшен |
|---|---|---|---|
| ОС | macOS / Windows | Linux сервер | Linux сервер |
| База данных | SQLite / локальный MySQL | MySQL кластер | MySQL кластер с репликацией |
| Нагрузка | 1 пользователь | Симуляция 10–100 | 1000+ реальных |
| Данные | Фикстуры | Маскированные | Реальные |
| CDN / кэш | Нет | Частично | Полностью |
Первая и самая частая причина — разные версии зависимостей. Разработчик устанавливает пакет локально с флагом --save, но забывает обновить package.json или lock-файл. При деплое на проде устанавливается другая версия, которая ведёт себя иначе. Для npm-экосистемы lock-файл полностью решает проблему, для других менеджеров пакетов — аналогичные механизмы (Gemfile.lock, Podfile.lock, pubspec.lock).
Вторая причина — отсутствующие или лишние переменные окружения. Разработчик использует .env файл на локальной машине, но не добавляет соответствующие переменные в CI/CD пайплайн или на сервер. Результат — код падает с ошибкой подключения к API или базе данных. По данным GitLab DevSecOps Survey 2023, 27% инцидентов на проде связаны с некорректными переменными окружения.
Третья причина — состояние базы данных. На стейджинге БД может содержать записи, которых нет на проде, или наоборот — не хватать миграций. Типичный сценарий: разработчик пишет код, который работает с новым полем в таблице, но миграция ещё не применена на проде. Миграционная стратегия с обратной совместимостью — единственный способ избежать таких ситуаций.
Четвёртая причина — региональные и языковые настройки. Форматирование дат, разделители дробных чисел, кодировка текста — всё это может различаться на локальной машине разработчика и сервере. Особенно актуально для проектов с интернационализацией. Решение — явно указывать locale в конфигурации приложения и не полагаться на системные настройки.
Первый шаг — сравнить логи обоих окружений. Разница в уровне логирования часто скрывает причину: на проде может быть включён INFO, а на стейджинге DEBUG. Настройте одинаковый уровень логирования и убедитесь, что оба окружения пишут в формате, позволяющем машинное сравнение. Используйте централизованные системы сбора логов — Sentry, Datadog, ELK Stack.
Второй шаг — проверить версии зависимостей. Сравните lock-файлы, выведите список установленных пакетов на обоих окружениях. Разница в минорной или патч-версии — наиболее вероятная причина расхождения. Инструменты вроде npm ls, pip freeze, mvn dependency:tree помогут быстро выявить несоответствия.
Третий шаг — воспроизвести окружение продакшена локально. Используйте Docker Compose или аналогичные инструменты для поднятия точной копии продакшен-инфраструктуры. Если баг воспроизводится в локальном контейнере — значит проблема в коде, а не в окружении. Если не воспроизводится — ищите различие в конфигурации.
Четвёртый шаг — проверить feature flags и A/B тесты. Возможно, на проде код работает в другом режиме, потому что включён не тот флаг. По данным LaunchDarkly State of Feature Management 2023, до 40% неожиданного поведения на проде связано с некорректными значениями feature flags. Единый манифест флагов для всех окружений решает эту проблему.
Главный инструмент предотвращения — Infrastructure as Code (IaC). Все окружения должны описываться в коде: Dockerfile, docker-compose.yml, Terraform-скрипты или Ansible-плейбуки. Ручные изменения на сервере запрещены — любое изменение конфигурации проходит через репозиторий и code review. Это гарантирует, что все окружения имеют одинаковую конфигурацию.
Второй по важности инструмент — единый CI/CD пайплайн. Один и тот же скрипт сборки, тестирования и деплоя должен использоваться для всех окружений. Разница — только в target-переменных (URL, ключи). Если пайплайн для стейджинга и продакшена различается по шагам — расхождения неизбежны.
Третий инструмент — автоматическая синхронизация данных. Регулярно (раз в сутки или по расписанию) обновляйте стейджинг анонимизированной копией продакшен-базы. Это позволяет тестировать код на реальных данных, а не на синтетических фикстурах. Инструменты: pg_dump/pg_restore для PostgreSQL, mysqldump для MySQL, специализированные сервисы вроде DataGrip.
Четвёртый — мониторинг расхождений. Настройте оповещения при обнаружении различий между стейджингом и продакшеном. Простой скрипт, сравнивающий хэши конфигурационных файлов или версии установленных пакетов, сэкономит часы отладки. Профилактика всегда дешевле диагностики: предотвращение расхождения окружений требует меньше усилий, чем поиск причины бага «на проде работает».
Часто задаваемые вопросы
В первом случае баг виден на стейджинге, но не на проде. Во втором — баг видят все, кроме разработчика, у которого код работает локально. Общий корень — в расхождении окружений, но проявляется ситуация на разных этапах.
Покажите, что баг на стейджинге — это баг, который уже готов уйти на продакшен с ближайшим деплоем. Исправление сейчас обойдётся дешевле, чем hotfix под давлением пользователей. Приведите примеры из истории проекта.
По данным DORA 2023, около 25–30% инцидентов на проде вызваны различиями между окружениями. В командах без контейнеризации этот показатель достигает 50%. Контейнеризация снижает его до 10–15%.
Да, это одна из частых причин. На проде включён CDN, Varnish или Redis-кэш, а на стейджинге — нет. Если баг связан с отдачей закэшированных данных, на стейджинге он проявится, а на проде будет скрыт кэшем.
Docker гарантирует идентичность окружения на всех этапах: разработка, тестирование, стейджинг, продакшен. Если образ собран один раз и используется везде — расхождение версий и конфигураций исключено. Единый образ — основа повторяемости деплоя.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также