Deployment vs Release: когда пользователи действительно получают новую версию

Ваша команда только что задеплоила версию 1.2.0 в production. Артефакт на сервере, приложение работает, все health-чеки зелёные. Значит ли это, что все пользователи уже используют новые функции? Скорее всего, нет.

Возможно, команда намеренно скрыла некоторые фичи, пока мониторит стабильность. Может быть, деплой прошёл на новый сервер, который ещё не подключён к пользователям. Разрыв между «код работает» и «пользователи могут им пользоваться» шире, чем думает большинство команд.

Разница между Deployment и Release

Deployment — это техническое действие. Вы размещаете артефакт в среде и запускаете его. Сервер принимает новый бинарник, миграция БД завершается, приложение начинает отвечать на запросы. С точки зрения инфраструктуры задача выполнена.

Следующая диаграмма показывает, как расходятся deployment и release:

flowchart TD A[Code Commit] --> B[Build & Test] B --> C[Deploy to Production] C --> D{Release Strategy?} D -->|Feature Flags| E[Feature Flag Off] D -->|Canary| F[Route 5% Traffic] D -->|Blue-Green| G[Deploy to Inactive Env] E --> H[Enable Flag for Users] F --> I[Monitor & Increase %] G --> J[Switch Traffic] H --> K[Users Access Feature] I --> K J --> K style C fill:#4a90d9,color:#fff style K fill:#27ae60,color:#fff

Release — это бизнес-решение. Момент, когда фича или исправление становятся доступны пользователям. Деплой может произойти без релиза, но релиз невозможен без деплоя.

Это различие важно, потому что оно меняет подход к рискам. Когда деплой и релиз — одно и то же, каждый деплой несёт полную нагрузку влияния на пользователей. Когда вы их разделяете, у вас появляется пространство для манёвра.

Feature Flags: простейшее разделение

Feature flags — самый распространённый способ отделить деплой от релиза. Вы добавляете код, который может включать или отключать фичи без переразвёртывания. Новая версия уходит в production с несколькими фичами, но активна только одна — для небольшой группы пользователей.

Вот простой пример конфигурации feature flag в YAML:

# config/feature-flags.yaml
features:
  new-checkout:
    enabled: false
    description: "Новый流程 оформления заказа с оплатой на одной странице"
    rollout_percentage: 0
  dark-mode:
    enabled: true
    description: "Переключатель тёмной темы для всех пользователей"
    rollout_percentage: 100

Когда команда готова выпустить новый чек-аут, они меняют enabled: false на enabled: true и обновляют процент раскатки. Никаких изменений кода, никакого передеплоя — только обновление конфигурации, которое вступает в силу немедленно.

Если фича работает хорошо, вы открываете её большему числу пользователей. Если что-то ломается — выключаете флаг. Никакого отката, никакого экстренного деплоя. Остальная часть приложения продолжает работать в штатном режиме.

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

Canary Releases: тестирование на реальном трафике

Canary-релизы развивают разделение дальше. Вы деплоите новую версию в production, но направляете на неё лишь небольшой процент пользователей — скажем, 5%. Эта группа получает новый код, остальные остаются на старой версии.

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

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

Blue-Green Deployment: разделение на уровне инфраструктуры

Blue-green deployment разделяет релиз и деплой на уровне инфраструктуры. У вас два идентичных production-окружения: blue и green. Старая версия работает на blue. Вы деплоите новую версию на green, пока blue обслуживает всех пользователей.

Когда вы уверены, что green стабилен, вы переключаете трафик с blue на green. Релиз происходит в момент переключения трафика, а не когда деплой завершился. Если после переключения что-то пошло не так — вы переключаете трафик обратно на blue.

Этот паттерн полезен для приложений, где feature flags использовать сложно, или где изменения слишком фундаментальны для переключения флагом. Изменения схемы БД, мажорные обновления фреймворков или модификации инфраструктуры часто выигрывают от blue-green деплоя.

Почему разделение Deployment и Release важно

Разделение даёт контроль над временем. Вы можете деплоить в 2 часа ночи, когда трафик низкий, но отложить релиз до утра, когда команда готова мониторить. Вы можете деплоить несколько раз в день, не беспокоясь о disruption пользователей, потому что релиз — это отдельное решение.

Это также меняет подход к проблемам. Когда деплой и релиз связаны, плохой деплой означает, что пользователи сразу видят ошибки. Когда они разделены, у вас есть время обнаружить проблемы до того, как они затронут пользователей. Сигналы health-чеков после деплоя говорят, что сервер работает. Сигналы после релиза говорят, что пользователи довольны.

За чем следить после релиза

Релиз — это момент, когда пользователи начинают ощущать ваши изменения. До релиза всё под вашим контролем. После релиза в дело вступают пользователи. Если есть проблема — они чувствуют её первыми.

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

После релиза нужно мониторить иначе. Смотрите на пользовательские метрики: время загрузки страниц, процент успешных транзакций, частоту ошибок по фичам. Сравнивайте с базовой линией до релиза. Зелёный деплой с плохим релизом — всё равно плохой результат.

Практический чек-лист для следующего релиза

Прежде чем объявить релиз завершённым, проверьте:

  • Можете ли вы откатиться без передеплоя? Если нет — каков план отката?
  • Знаете ли вы, какие пользователи видят новую версию? Если делаете canary — убедитесь, что сплит трафика работает.
  • Мониторите ли вы пользовательские метрики, а не только здоровье сервера? Здоровье сервера говорит, что приложение запущено. Пользовательские метрики — что оно работает.
  • Есть ли способ отключить фичу без передеплоя? Если не используете feature flags — подумайте о их внедрении до следующего релиза.
  • Кто должен знать о релизе? Команды поддержки, документации и другие стейкхолдеры должны быть оповещены.

Итог

Deployment помещает код на сервер. Release помещает фичи в руки пользователей. Относитесь к ним как к разным решениям — и вы получите возможность деплоить уверенно, релизить осторожно и быстро восстанавливаться, когда что-то идёт не так. Лучшие команды не просто хорошо деплоят — они хорошо релизят, потому что знают: это не одно и то же.