← Все материалы
Бесплатно

«Тестирую на проде»: однажды это сотрёт базу

Одна команда стирает базу клиентов за секунды. У тебя одна среда: ты пробуешь новое там же, где живут данные людей. Так можно до первой удаляющей команды, которая пошла не туда. На реальных провалах разбираю, почему так выходит даже у опытных команд, и как поднять вторую среду за вечер, чаще всего бесплатно. Внутри: модель из трёх сред, четыре истории, карта по слоям и рецепт на один вечер.

У тебя одна среда. Ты пробуешь новое прямо там, где живут твои пользователи и их данные. Так можно ровно до того дня, когда одна команда, одна забытая галочка или одна услужливая нейросеть-помощник не сотрёт всё разом. А бэкапа, скорее всего, нет. Дело не в неосторожности. Просто между твоим экспериментом и боевыми данными нет стены. Внутри разбираю, почему так выходит даже у опытных команд, и как поставить эту стену самому, не разбираясь в серверах.

Что внутри

Модель из трёх сред

Где ломаешь, где репетируешь, где живут клиенты, и почему ты путаешь первое с третьим.

Четыре реальных провала

Как опытные инженеры, целая платформа и джуниор в первый день стирали боевые базы по одной причине.

Карта по слоям

Что поднять для фронта, что для базы, что для бэкенда. С граблями, на которых спотыкаются.

Рецепт на один вечер

Буквальные шаги, как завести вторую базу, чтобы ни одна команда больше не дотянулась до клиентов.

Короткий ответ: потому что у тебя нет второй среды.

Место, где ты пробуешь новое, и место, где лежат данные клиентов, у тебя одно. Значит, любая проверка идёт по живому. Правка, миграция, даже невинное «дай-ка гляну, сколько там записей» бьёт по боевой базе. И всё работает до первой удаляющей команды, которая пошла не туда. Вторая среда нужна не только большим командам. Это стена между твоим экспериментом и клиентами, и поставить её дешевле, чем потом искать бэкап, которого нет.

Без «у вас всё горит»

Я разбираю такие вещи спокойно, на живых проектах. Если интересно смотреть работу по ходу, у меня есть [Telegram-канал](https://t.me/fomdi). Подписывайся.

Что такое вторая среда и почему её у тебя нет

В нормальном проекте сред три, и у каждой своя роль.

Первая, разработка. Это твоя машина. Тут ты ломаешь свободно, упало, никто не заметил. Вторая, репетиция, её часто называют английским словом staging. Отдельная копия, максимально похожая на боевую: тот же код, та же база по типу, те же настройки, но другие данные и другой адрес. Сюда ты выкатываешь правку перед боем и прокликиваешь руками. Сломалось, сломалось здесь, не у клиента. И третья, бой, по-английски production. То, чем пользуются живые люди. Единственное место, где ошибка стоит денег и данных.

У тебя из этих трёх есть одна, и она же бой. Поэтому ты и завис на «локально работает, на проде нет»: нет промежуточного шага, где это ловится. Кстати, «среда» и «окружение» в туториалах это одно и то же слово, не пугайся, если встретишь оба.

Принцип тут простой. Среды надо держать похожими, чтобы правка вела себя одинаково везде. Если локально у тебя одна база, а в бою другая, половина сюрпризов вылезет именно в бою, потому что только там настоящая база. Не упрощай среду разработки ради сиюминутного удобства. Это удобство потом оборачивается ночным разбором.

Открытая тетрадь на тёмном столе под брасс-лампой, от руки нарисована схема из трёх рамок со стрелками, зелёная резинка-закладка
Три среды: где ломаешь, где репетируешь, где живут клиенты

Три среды и их роли

Разработка
Бой (production)

Где это

Разработка

Твоя машина

Бой (production)

Живой сервер

Что тут можно

Разработка

Ломать всё

Бой (production)

Ничего лишнего

Данные

Разработка

Тестовые

Бой (production)

Настоящие клиенты

Цена ошибки

Разработка

Ноль

Бой (production)

Деньги и данные

Между ними

Разработка

Репетиция (staging): копия боя, другие данные

Бой (production)

Сюда выкатываешь только проверенное

Почему «потестю на проде» однажды стирает данные

Это не страшилка для новичков, на это наступали инженеры с двадцатилетним стажем и целые компании. Четыре истории. Имена убираю намеренно, важна форма, а не вывеска.

Крупный хостинг кода для разработчиков. Инженер чинил отстающую копию базы и одной командой удаления попал не по той машине. По боевой. Из трёхсот гигабайт осталось около четырёх. Пошли за бэкапом, а там пять разных способов резервного копирования, и ни один не работал по-настоящему. Спасла случайная копия шестичасовой давности, которая лежала на отдельной тестовой среде. Получается, именно вторая среда оказалась единственным выжившим бэкапом.

Платформа, где приложения собирают через нейросеть, прошлым летом. Человек прямым текстом сказал своему AI-помощнику: код не трогай, заморозка. Тот всё равно выполнил удаление и снёс боевую базу. Потом честно написал что-то вроде «я уничтожил месяцы работы за секунды». После этой истории платформа спешно сделала то, чего у неё раньше не было. Развела базу разработки и боевую базу автоматически. Раньше помощник в режиме разработки спокойно дотягивался до прода.

Третья короче. Большой облачный сервис хранения, инженер во время отладки ввёл один параметр команды не так, и выключилось серверов сильно больше, чем он планировал. Половина знакомых тебе сайтов легла на несколько часов.

И четвёртая, самая обидная. Джуниор в первый рабочий день открыл инструкцию по настройке и запустил скрипт по примеру из неё. А в примере по чьему-то недосмотру стояли боевые доступы. Скрипт почистил прод. Парня уволили, хотя виноват был не он.

Четыре провала, одна форма

Хостинг кода

Удаление пошло по боевой машине вместо запасной. Пять бэкапов, ни один не сработал. Спасла случайная копия на отдельной среде.

Платформа на нейросети

AI-помощник снёс прод вопреки прямому «не трогай». Дев и бой не были разделены. После этого платформа развела их автоматически.

Облачное хранилище

Один параметр команды введён не так при отладке. Выключилось серверов больше, чем планировали, лёг целый регион на часы.

Джуниор в первый день

В инструкции по настройке по недосмотру стояли боевые доступы. Тестовый скрипт почистил прод. Уволили, хотя виноват был не он.

Старый аналоговый распредщит на стене ночью, ряды тумблеров и тканевых проводов, один тумблер поднят и рядом горит эмеральд-индикатор
Одна команда дотянулась до боя: один контур ушёл в живую линию
Виновата не усталость, виновата схема

Четыре разных истории, а провал по сути двойной. Сначала опасная команда дотянулась до боя: где-то потому, что дев и прод были не разделены, где-то потому, что человек осознанно работал по живому. А потом не сработала страховка: бэкапа не было или он был мёртвый. Хватило одной из двух дыр, чтобы потерять данные. Вторая среда закрывает первую дыру, бэкап вторую. Виновата не усталость на третьем часу. Виновата схема, где одна команда дотягивается до клиентов и поймать её нечем.

Есть проект, который страшно трогать?

Если там уже живые люди, это чинится. Я подхватываю и стабилизирую такие проекты: развожу среды и ставлю барьеры, чтобы ушло «только бы не сломалось». Можно и по-минимуму, через настройку AI-рабочего места, где правильное разделение сред уже встроено.

Посмотреть, как помогаю

Как одна база превращает любую команду в катастрофу

Самый частый сценарий даже не про злой умысел. Он про обычную задачу.

Человек хотел просто посмотреть, сколько у него регистраций. Вместо маленькой админ-страницы он подключился напрямую к боевой базе и выполнил там запрос. А ещё раньше отключил у себя защитный вопрос «ты уверен», чтобы не мешал. Одно неловкое движение, и данных нет.

Другой случай. Скрипт должен был удалить одного клиента. Но в удаляющей команде забыли условие «только этого». Без условия команда означает «удали всех». Скрипт уехал в бой и стёр всю базу клиентов. Бэкап был двухмесячной давности.

И самый близкий тебе случай. Миграция, которая «локально прошла нормально», на деле удалила все данные. Миграция это команда, которая меняет структуру базы: добавляет таблицу, удаляет колонку. А удалила она всё потому, что локальные настройки смотрели в боевую базу. Человек думал, что играет на своей копии, а играл на бою.

Во всех трёх одно и то же. Адрес базы у разработки и у боя совпадал. Этот адрес живёт в одной строчке настроек, её называют строкой подключения, и выглядит она примерно как DATABASE_URL=... Одна эта строчка и есть вся разница между «бью по тесту» и «бью по клиентам». Пока она одна на всё, ты не разработчик со своей песочницей. Ты человек с прямым доступом к проду, которому пока везёт. До поры.

Как поднять вторую среду на своём стеке

В 2026 году это делается за вечер, а часто бесплатно. Порядок такой: отдельная база, отдельные настройки под неё, отдельный адрес. Самое важное тут первое, его и пропускают чаще всего.

Если ты не сделаешь ничего другого, сделай хотя бы это. Заведи вторую базу данных и второй файл с настройками под неё. Локально работай со второй базой. Боевую строку подключения держи только в бою. Всё. Этого одного достаточно, чтобы ни одна твоя локальная команда не дотянулась до клиентов, будь то миграция, случайный запрос или услужливый помощник-нейросеть.

Дальше по слоям, и тут проще, чем кажется. У приложения обычно три слоя: фронт (то, что видно в браузере), база (где лежат данные) и бэкенд (что крутится на сервере между ними). Вторую среду можно поднять на каждом.

С чего начать

Шаг, что закрывает почти всё

Вторая база плюс второй файл настроек под неё. Локальную разработку перенаправить на вторую базу. Полчаса работы.

Фронт бесплатно

Preview-деплои дают живой адрес на каждую ветку. Но по умолчанию ходят в боевую базу, развести обязательно.

База по кнопке

Копия или пустая база за минуту. Помни: копия прода это реальные данные клиентов, для экспериментов бери пустую.

Бэкенд целиком

Отдельное окружение «как бой» с пустой своей базой. Второй экземпляр приложения, который не трогает живой.

Фронт

Площадки вроде Vercel и Netlify дают preview-деплои. Каждая ветка в твоём проекте получает свой живой адрес. Это удобно, но есть ловушка, о которой молчат: такой адрес по умолчанию ходит в ту же боевую базу. То есть из коробки это репетиция картинки, а не репетиция данных. Базу под него надо развести руками, иначе твой «тест» пишет в прод.

База

Современные базы умеют делать копию по кнопке. У Neon это называется веткой, как в гите: жмёшь, и получаешь отдельную копию базы за секунду. Важный момент. Копия боевой базы это копия реальных данных клиентов, те же телефоны и почты. Относись к ней как к бою и не раздавай доступ. Для большинства экспериментов тебе безопаснее пустая база или база, наполненная выдуманными тестовыми данными. У Supabase ветка как раз стартует без боевых данных, чтобы ты случайно не утащил чужое.

Бэкенд

Площадки вроде Railway и Render умеют поднять отдельное окружение «как бой», но с пустой, отдельной базой. Это второй полноценный экземпляр твоего приложения, который не трогает живой. И ещё про локальную работу: если в бою у тебя один набор сервисов, держи такой же у себя, а не упрощённый. Тогда «локально работает, на проде нет» почти исчезает.

Из чего собрать вторую среду

Фронт
База и бэкенд

Чем поднять

Фронт

Preview-деплои (Vercel, Netlify)

База и бэкенд

Копия или пустая база (Neon, Supabase), окружение (Railway, Render)

Что получаешь

Фронт

Живой адрес на каждую ветку

База и бэкенд

Вторую базу и копию бэка как в бою

Грабли

Фронт

По умолчанию ходит в боевую базу

База и бэкенд

Копия прода это те же данные клиентов, базу надо наполнить тестовыми

Цена

Фронт

Бесплатно на старте

База и бэкенд

Бесплатный тариф со сном в простое или по потреблению

Два монитора на тёмном столе: в одном редактор с конфигом, в другом тёмная панель с веткой базы и эмеральд-графиком
Два файла настроек и проверка, куда реально смотрит вторая среда

Рецепт на один вечер

Чтобы это не осталось теорией, вот один конкретный путь до конца. Под базу беру Neon, он бесплатный на старте.

  1. Заводишь на Neon отдельный проект под тесты, он сразу даёт строку подключения.
  2. Копируешь эту строку в свой второй файл настроек, тот, что для разработки.
  3. Проверяешь, что локально приложение читает именно этот файл, а не боевой.
  4. Делаешь любую безобидную правку в базе через приложение и смотришь, что изменилось в тестовом проекте Neon, а не в боевом. Если изменилось в тестовом, стена стоит.

Шаг четыре это и есть главная проверка. Она отвечает на единственный важный вопрос: куда на самом деле смотрит моя вторая среда. Если в боевую базу, ты просто переименовал прод, а не развёл среды.

Как выглядят два файла настроек

Внизу пример. Один файл для твоей машины и репетиции, второй только для боя. Главное, что у них разный адрес базы в той самой строке подключения.

Два файла настроек · разный адрес базы
# .env.development  (твоя машина и репетиция)
DATABASE_URL="postgres://localhost:5432/myapp_dev"

# .env.production  (только бой, живёт в настройках хостинга)
DATABASE_URL="postgres://prod-host:5432/myapp_live"

Тот же файл, что подвёл джуниора из истории выше, спасает, если он разный для разных сред и не уезжает в гит. Добавь его в список игнорируемых файлов сразу, до первого коммита, чтобы боевые доступы не утекли в репозиторий.

Проверь, куда смотрит репетиция

Повторю самую частую ловушку, потому что на ней спотыкаются почти все. На многих площадках предпросмотр по умолчанию берёт настройки с боевого сервиса. Значит, твоя «репетиция» может молча смотреть в боевую базу. Проверь это первым делом тем самым шагом четыре из рецепта: репетиция должна писать в отдельную базу, а не в ту же самую под другим именем.

«Но я не могу позволить себе вторую среду»

Можешь. На старте вторая среда обходится примерно бесплатно.

Preview-деплои бесплатны. У баз есть бесплатные тарифы с копиями, и они гаснут до нуля в простое, так что без работы за них не капает. Отдельные окружения на бэкенд-площадках поднимаются по требованию. Оговорюсь честно: бесплатно это в пределах лимитов по объёму и времени, а спящая база при первом запросе просыпается пару секунд, не пугайся, что «тормозит». Всё равно реальная цена близка к нулю. А цена обратного это стёртая база клиентов и бэкап двухмесячной давности. Вот эти два числа и сравни.

А аккуратно тестить на проде совсем нельзя?

Да, опытные команды тестируют в проде всегда. А ты пока нет, и это правильно. По-настоящему проверить поведение под реальной нагрузкой можно только на бою, тут они правы. Но говорят они про другое. У них боевые проверки идут под наблюдением, с предохранителями, с возможностью мгновенно откатить.

Тебе сначала стена. Сначала отдельная база, до которой удаляющая команда физически не дотянется. А «безопасный прод» с постепенной выкаткой и переключателями функций это следующая глава, до которой ты спокойно дорастёшь. Не путай «я слежу за реальным поведением под нагрузкой» и «я правлю боевую базу руками и надеюсь». Первое называется инженерией. Второе ближе к рулетке.

Частые вопросы

Локальная это твоя машина, там всё твоё и сломать не страшно. Staging это отдельная копия, максимально похожая на боевую, общая точка перед выкаткой. Разница в том, что staging ведёт себя как бой, а локальная может врать из-за мелких отличий.
Тебе нужны минимум две: где ломаешь и где живут клиенты. Если развести их хотя бы базой и настройками, ты уже закрыл главный риск. Полноценную репетицию добавишь, когда проект подрастёт.
Это разные страховки. Бэкап помогает после потери. Вторая среда не даёт потере случиться. Нужны обе, но если выбирать первый шаг, разделение сред дешевле и спасает чаще.
Завести вторую базу данных и второй файл настроек под неё. Перенаправить локальную разработку на вторую базу. Боевую строку подключения оставить только в бою. Проверить, что локальный запрос меняет тестовую базу, а не боевую.
Может, если у него есть доступ к боевой базе. Обычно он получает его через ту же строку подключения в твоих настройках, через подключённый коннектор к базе или через доступ к терминалу. Поэтому держи дев и бой на разных базах, не давай помощнику боевые доступы и не отключай защитные вопросы на удаление.

Хочешь, чтобы кто-то посмотрел твой проект?

Я Дмитрий Фоменко, AI-инженер из Минска. Восемь лет в разработке, часто подхватываю чужие проекты, собранные через нейросеть, когда их уже страшно трогать. Помогу развести среды и поставить барьеры: разбор архитектуры, менторская сессия или менторство по вайб-кодингу.

Разобрать мой проект
Если застрял

Если застрял на каком-то шаге или не уверен, куда смотрит твоя вторая среда, напиши. Отвечаю по мере возможности.