Где на самом деле выполняется ваш код: понимание окружений
Вы только что закончили сборку приложения. Тесты пройдены, сборка завершена, артефакт благополучно лежит в реестре. Теперь возникает вопрос, с которым рано или поздно сталкивается каждая команда: куда это развернуть, чтобы люди могли реально пользоваться?
Очевидный ответ — «на сервер». Но за этим простым ответом скрывается более важная реальность. Вашему приложению, скорее всего, придется побывать в нескольких разных местах, прежде чем оно доберется до реальных пользователей. У каждого из этих мест своя цель, и относиться ко всем одинаково — верный путь к сломанным релизам и злым пользователям.
Первое место: разработка
Когда вы пишете код, вам нужно пространство для свободных экспериментов. Это ваше окружение разработки. Для многих разработчиков оно начинается на собственном ноутбуке. Вы запускаете приложение локально, вносите изменения, ломаете всё, чините и повторяете. Никто не страдает, потому что никто, кроме вас, этот экземпляр не использует.
Некоторые команды используют общий сервер разработки. Несколько разработчиков пушат код на общую машину, где можно протестировать интеграцию до того, как всё станет серьезным. В любом случае правила одни: данные могут быть фейковыми, падения допустимы, стабильность не является целью. Смысл здесь — в исследовании и итерациях.
Окружения разработки должны быть зоной низких ставок. Если нужно перезапустить приложение десять раз за час — без проблем. Если случайно удалил базу — восстанавливаешься из бэкапа с тестовыми данными и движешься дальше. Эта свобода критически важна для быстрой разработки.
Путь вашего артефакта через эти окружения выглядит так:
Почти продакшен: стейджинг
В какой-то момент ваш код должен доказать, что выживет в условиях, приближенных к реальным. Для этого нужен стейджинг.
Стейджинг создается так, чтобы максимально повторять продакшен. Конфигурация сервера должна совпадать. Версия базы данных должна быть той же. Способ запуска приложения, подключения к сервисам и обработки запросов — всё должно быть идентично тому, что будет в продакшене. Единственное, чего нет — реальных пользователей и реальных данных.
Это окружение существует для одной цели: выявить проблемы до того, как они доберутся до пользователей. Если миграция упадет — вы узнаете об этом на стейджинге. Если настройка конфига неверна — вы обнаружите это здесь. Если новая функция ломается под реалистичной нагрузкой — вы увидите это до того, как кто-то пожалуется.
Команды часто совершают ошибку, позволяя стейджингу расходиться с продакшеном. Может быть, на сервере стейджинга меньше памяти, или используется другой движок базы данных, или стоит старая версия ОС. Эти различия сводят на нет весь смысл. Если стейджинг — не точная копия, тесты, которые вы там проводите, мало что скажут о поведении в продакшене.
Настоящее место: продакшен
Продакшен — это место, где ваше приложение встречается со своим истинным предназначением. Реальные пользователи отправляют реальные запросы. Реальные данные обрабатываются, хранятся и возвращаются. У каждого вашего изменения есть реальные последствия.
Поскольку ставки выше, продакшеном управляют иначе. Доступ ограничен. Изменения проходят более тщательное ревью. Развертывания следуют более строгим процедурам. В продакшене не экспериментируют. Не пушат непротестированный код. Не вносят ad-hoc изменения в конфигурацию, не понимая их влияния.
Напряжение между скоростью разработки и стабильностью продакшена — постоянная сила в любой инженерной команде. Хочется двигаться быстро, но нужно и поддерживать сервис в рабочем состоянии. Окружения помогают управлять этим напряжением, предоставляя разные пространства для разных уровней риска.
Один артефакт, разные места
Вот принцип, который отделяет гладкие развертывания от хаотичных: один и тот же артефакт должен работать и на стейджинге, и в продакшене.
Звучит очевидно, но многие команды нарушают это, даже не осознавая. Они собирают приложение для стейджинга, прогоняют тесты, а потом собирают заново для продакшена. Может быть, сборка для продакшена использует другие флаги. Может быть, зависимости разрешаются немного иначе. Может быть, кто-то вручную пропатчил что-то на стейджинге, но забыл применить то же исправление к продакшен-сборке.
Когда артефакт меняется между окружениями, ваши тесты на стейджинге теряют смысл. Вы тестировали версию A, а развернули версию B. Любая уверенность, полученная от прогона на стейджинге, была ложной.
Решение простое: собирайте один раз, продвигайте один и тот же артефакт через окружения. Бинарник или образ контейнера, прошедший тесты на стейджинге, — это именно тот, что идет в продакшен. Никакой перекомпиляции. Никаких других флагов. Никаких ручных патчей. Просто один и тот же артефакт, развернутый в разных местах.
Как развертывание отличается в разных окружениях
Не все окружения нужно развертывать одинаково. Уровень осторожности и формальностей должен соответствовать риску.
В разработке можно развертывать автоматически при каждом коммите. Цена ошибки низкая, поэтому процесс может быть быстрым и нестрогим. Некоторые команды даже пропускают формальное развертывание и просто перезапускают приложение с последним кодом.
На стейджинге развертывание обычно происходит после прохождения базовых тестов. Процесс должен быть автоматизирован, но может включать шаги верификации. Нужно убедиться, что артефакт валиден, прежде чем он попадет на стейджинг-сервер.
В продакшене развертывание часто включает больше шагов. Могут потребоваться утверждения, запланированные окна развертывания в часы низкой нагрузки или постепенные выкатки, которые медленно перенаправляют трафик на новую версию. Точный процесс зависит от профиля риска вашего приложения, но паттерн неизменен: больше осторожности для окружений, влияющих на реальных пользователей.
Управление окружениями: единообразие
Каждым окружением нужно управлять воспроизводимым образом. Если настройка сервера стейджинга требует другого процесса, чем настройка продакшена, вы вносите переменные, которые могут вызвать проблемы.
Цель — единообразие. Способ размещения артефакта, запуска приложения и проверки его работоспособности должен быть одинаковым во всех окружениях. Единственные различия должны быть в значениях конфигурации: URL базы данных, API-ключи, фича-флаги.
Когда окружениями управляют непоследовательно, появляются странные баги. Фраза «на стейджинге работало» становится обычной, за ней следует недоумение, когда тот же артефакт падает в продакшене. В девяти случаях из десяти разница в том, как было настроено окружение, а не в самом коде.
Практический чек-лист для управления окружениями
- У каждого окружения есть четкая цель, задокументированная и понятная команде
- Стейдждинг зеркалирует продакшен по конфигурации, зависимостям и инфраструктуре
- Один и тот же бинарник артефакта продвигается через стейджинг в продакшен
- Процессы развертывания автоматизированы и воспроизводимы во всех окружениях
- Конфигурация, специфичная для окружения, отделена от кода приложения
- Доступ к продакшену ограничен и логируется
- Стейдждинг использует обезличенные или синтетические данные, похожие на продакшен-паттерны
Что дальше
Ваш артефакт теперь в нужном окружении. Он протестирован на стейджинге и продвинут в продакшен. Но его присутствие на сервере не означает, что пользователи его уже видят. Следующий шаг — решить, когда новая версия начнет обслуживать трафик. Именно это решение — момент между развертыванием и релизом — часто становится источником новых вызовов для многих команд.