Что вы на самом деле доставляете: артефакты и окружения
Вы пишете код на ноутбуке. Пушите его в репозиторий. Кто-то говорит: «Задеплой». Но что именно деплоится? Сырой исходный код из редактора? Не совсем. Между вашим ноутбуком и сервером происходит кое-что важное: код превращается в то, что сервер может реально запустить. Этот результат называется артефактом. А место, где он выполняется, называется окружением.
Понимание этих двух концепций меняет подход к доставке. Вместо «перемещения кода» вы начинаете думать о «доставке подготовленного пакета в нужное место».
Почему сырой код не сработает на сервере
Представьте, что вы написали Python-скрипт на ноутбуке. У вас стоит Python 3.11 и дюжина библиотек, установленных через pip. На ноутбуке — конкретная версия OpenSSL, определённая локаль и, возможно, переменные окружения, которые вы задали месяцы назад и забыли.
Теперь вы хотите запустить этот скрипт на production-сервере. Если просто скопировать сырые .py файлы, сервер должен иметь ту же версию Python, те же библиотеки и те же системные зависимости. Если хоть что-то не совпадает, скрипт может упасть неожиданным образом. Может, версия библиотеки другая. Может, на сервере нет компилятора для нативного расширения. Может, часовой пояс вызовет баг с парсингом даты, который проявится только в 2 часа ночи.
Именно поэтому сырой код не доставляют. Вы доставляете артефакт — самодостаточный пакет, содержащий всё необходимое для запуска приложения. Артефакт собирается один раз в контролируемом окружении, и этот же артефакт деплоится везде. Никакой пересборки, никаких сюрпризов «у меня работает».
Как выглядит артефакт
Артефакт — это результат процесса сборки. Его форма зависит от вашего технологического стека:
- Java: JAR или WAR-файл со скомпилированным байт-кодом и зависимостями.
- Go: Один бинарный файл без внешних зависимостей.
- Python: Wheel-файл или zip-архив со всеми библиотеками.
- Node.js / фронтенд: Папка с минифицированными HTML, CSS и JavaScript.
- Docker: Образ контейнера, упаковывающий приложение вместе с рантаймом.
Ключевое свойство: артефакт готов к запуску. Никакой компиляции, разрешения зависимостей или настройки окружения. Вы отдаёте его серверу — сервер запускает. Всё.
Куда попадают артефакты: окружения
Когда артефакт готов, нужно место для его запуска. Это место — окружение. Окружения — это не просто разные серверы. Это разные контексты с разными целями, данными, конфигурациями и уровнем риска.
Окружение разработки (Development)
Это ваш ноутбук или локальная машина. Здесь можно всё ломать без последствий. Экспериментальные ветки, удаление баз данных, сотни перезапусков сервисов — никто не пострадает. Данные — фейковые или сэмплированные. Конфигурация указывает на локальные сервисы. Цель — скорость и гибкость, а не стабильность.
Промежуточное окружение (Staging)
Staging — это копия production, настолько близкая, насколько это разумно. Те же характеристики железа, та же ОС, та же версия БД, та же топология сети. Данные могут быть обезличенными production-данными или синтетическими, имитирующими реальные паттерны использования.
Staging существует, чтобы ловить проблемы до попадания к пользователям. Сюда деплоится артефакт, прогоняются тесты, выполняются ручные проверки, верифицируется совместимость новой версии с существующей инфраструктурой. Если что-то сломалось — неприятно, но не катастрофично. Пользователи не затронуты.
Production-окружение
Здесь с приложением работают реальные пользователи. В production — реальные данные, реальный трафик и реальные последствия ошибок. Конфигурация тщательно управляется: credentials к БД, API-ключи, feature flags, пулы соединений — всё настроено для работы «вживую».
Деплой в production требует осторожности. Используются постепенные выкатки, canary-релизы, blue-green-стратегии. Нужны мониторинг, оповещения и план отката. Артефакт, попадающий в production, должен быть тем же самым, что прошёл staging, а не другой сборкой.
Почему это различие важно
Многие команды относятся к окружениям просто как к «разным серверам». Деплоят везде одинаково, одними и теми же скриптами, с одним уровнем осторожности. Это ошибка.
У каждого окружения разные требования:
- Данные: В разработке — фейковые. В staging — возможно, обезличенные production. В production — реальные. Никогда не подключайте staging к production-базе, даже случайно.
- Конфигурация: Эндпоинты API, feature flags, лимиты ресурсов различаются. Файл конфигурации, работающий в разработке, может уронить production, если указывает на локальную БД.
- Допустимость сбоев: В разработке можно перезапускать сервисы когда угодно. В production перезапуск может оборвать активные соединения и разозлить пользователей. Одно и то же действие имеет разные последствия в зависимости от того, где вы его делаете.
Когда вы воспринимаете окружения как разные контексты, вы проектируете процесс деплоя соответственно. Вы не запускаете один и тот же скрипт на staging и production без анализа различий. Вы не предполагаете, что работающее в разработке сработает в production. Вы проверяете на каждом шагу.
Пайплайн связывает артефакты с окружениями
CI/CD-пайплайн — это мост между артефактами и окружениями. Он собирает артефакт один раз, сохраняет в реестре и продвигает по окружениям. Тот же артефакт, который прошёл тесты в staging, деплоится в production. Никакой пересборки, перекомпиляции, «дай-ка я быстро поправлю на сервере».
Путь от кода до production выглядит так:
Вот почему управление артефактами так важно. Нужно место для хранения, версионирования и отслеживания: какой артефакт работает в каком окружении. Когда сообщают о баге, вы должны сказать: «Это версия 1.4.3 артефакта, собранная из коммита abc123, сейчас в production». Без такой прослеживаемости отладка превращается в гадание.
Практический чек-лист
Перед следующим деплоем проверьте:
- Артефакт собирается один раз и сохраняется в реестре?
- Один и тот же артефакт деплоится в staging и production?
- У каждого окружения своя конфигурация, отдельная от артефакта?
- Можете ли вы прямо сейчас сказать, какая версия артефакта работает в каждом окружении?
- Есть ли план отката, использующий предыдущий артефакт, а не пересборку?
Конкретный вывод
Артефакты и окружения — не абстрактные понятия. Это то, с чем вы работаете каждый раз, когда доставляете софт. Артефакт — то, что вы отправляете. Окружение — то, куда оно попадает. Держите их раздельно, обеспечьте прослеживаемость и никогда не пересобирайте артефакт только потому, что деплоите в другое окружение. Ваш production-сервер должен запускать тот же самый пакет, который прошёл тесты.