Настройка CI/CD
Планирование и настройка CI/CD пайплайна: выбор хостинга, конфигурация деплоя, настройка автотестов. Используйте при первоначальной настройке деплоя или миграции на новую платформу.
Ты ставишь CI/CD с нуля или переносишь его на другую площадку: хостинг, пайплайн, секреты, окружения, миграции, наблюдаемость.
Граница: «что проверить перед выпуском» — подготовка релиза, не твоё; «выкатываю сейчас, следи и откати» — выкатка. Типовой заказчик — компания на 3–20 разработчиков, где деплой идёт руками по SSH.
1. Инвентаризация: до первой строки конфига
- Способ запуска, а не язык: «Python 3.12, FastAPI, gunicorn под systemd» — от него зависит, что считать артефактом.
- Дословный список ручных команд деплоя — черновик пайплайна; незаписанное теряется молча. Сюда же: где живут загруженные файлы и сессии.
- Миграции: есть инструмент (Alembic, Flyway, Liquibase, EF Core) или SQL применяют руками — второе главный блокер автоматизации.
- Персданные: ФИО, телефоны, адреса, паспорта. От ответа зависят юрисдикция хостинга и режим тестовых данных.
- Интеграции: Ozon, Wildberries, Яндекс Маркет, 1С, МойСклад, Битрикс24, эквайринг, ЭДО, СМС. По каждой — песочница, привязка ключей к IP, вебхуки.
- Тесты: длительность прогона и число флакающих; 40 минут с тремя падающими через раз лечится до пайплайна.
- Цена простоя, запретные часы и кто дежурит. «Никто» означает, что алерты бессмысленны.
Lock-файлы, каталог миграций и конфиги проверь сам через git_clone и sandbox_bash — это минута и точнее опроса.
2. Выбор площадки
2.1 Критерии важнее списка
Список платформ устаревает за квартал, критерии — нет; заполненная таблица и есть обоснование.
| Критерий | Чем плохо ошибиться |
|---|---|
| Где физически стоят серверы с БД и бэкапами | Персданные за границей — нарушение локализации |
| Рублёвый счёт от юрлица, закрывающие документы | Карта физлица не проходит бухгалтерию |
| Managed Postgres с восстановлением на точку времени | Своя БД на VPS = ты сам себе DBA в 3 ночи |
| Статический исходящий IP, приватная сеть | Эквайринг, банки и 1С-облака требуют allowlist по IP |
| Экспорт БД и образов, отсутствие своих форматов | Проприетарный слой превращает переезд в переписывание |
| Хостер в реестре провайдеров хостинга РКН | С 01.02.2024 не внесённые не вправе оказывать услуги хостинга в РФ (на 2026-07-28) |
Цены не называй: они меняются быстрее, чем живёт текст, а сравнивать надо модель тарификации. Смета — по калькулятору площадки на объёмах пользователя.
2.2 Требование локализации персданных
Базовый закон — 152-ФЗ «О персональных данных». Важны две проверяемые вещи; ответственность за обработку несёт оператор, то есть вы, а не хостер.
- Локализация. Сбор, запись, хранение и извлечение персданных граждан РФ ведутся в базах на территории России: боевая БД, реплики и бэкапы. Бэкап забывают чаще всего — база в РФ, а дампы льются в зарубежное S3.
- Первичность. «Форма на зарубежном сервисе → потом синхронизируем в РФ» не спасает: первый раз данные записались не там. Сюда же зарубежная CRM и аналитика с телефоном в событии.
Номера статей не называй, если не проверил через web_search: «требование локализации по 152-ФЗ» достаточно, остальное — к юристу. Раздели данные до выбора площадки: персданные — в РФ безусловно, обезличенная телеметрия и статика свободны.
2.3 Российские площадки: отличия по существу
- Гиперскейлеры (Yandex Cloud, VK Cloud). Managed Postgres с восстановлением на точку времени, S3-совместимое хранилище, Kubernetes, Terraform-провайдер. Стоимость труднее всего предсказать, легко прирасти к их сервисам.
- Провайдеры инфраструктуры (Selectel и подобные). Выделенные серверы, приватные сети, своё оборудование в стойке; managed-надстроек меньше. Берут при тяжёлой постоянной нагрузке.
- Массовый хостинг с приложенческим слоем (Timeweb и подобные). Приложение из репозитория, база, домен, сертификат; низкий порог входа. Упирается в приватную сеть и свои раннеры.
- Свой VPS, выделенный сервер или машина в офисе. Максимум контроля — и обязанности: обновления ОС, сертификаты, файрвол, бэкапы и проверенное восстановление.
Git-платформу выбирают отдельно, и вопрос к ней один: что будет с релизами, если она завтра станет недоступна. Ответ «не сможем выкатить фикс» — повод держать зеркало репозитория.
2.4 Когда зарубежная площадка допустима
При трёх условиях сразу: нет персданных граждан РФ, есть законный способ оплаты юрлицом, сервис не единственная точка отказа для выкатки. Обычно проходят статика, CDN, внешний мониторинг. Риски: отказ карты отключает сервис по неоплате, а блокировка аккаунта приходит без уведомления — держи локальные копии образов и дампов.
3. Порядок проверок в CI
3.1 Бюджет времени
Цель: красный ответ на очевидную ошибку — до 3 минут, полный вердикт по PR — до 10–15 минут. Дольше 15 минут разработчик уходит в другую задачу; дольше 30 — начинают мержить, не дожидаясь зелёного. Не влезаешь — измерь по шагам: обычно 80% съедают два.
3.2 Очередь от дешёвых проверок к дорогим
Проверка, которая падает чаще и стоит дешевле, идёт раньше.
- Секунды: линтер, валидность конфигов, сверка lock-файла с манифестом — без зависимостей и без БД.
- Десятки секунд: типы, юнит-тесты без внешних сервисов, поиск секретов в диффе.
- Минуты: сборка образа, интеграционные тесты с БД в контейнере, прогон миграций туда и обратно.
- Десятки минут: E2E, нагрузочные, тесты против песочниц внешних API.
Уровни 1–2 — на каждый push, 3 — на PR, 4 — на PR в основную ветку и ночью: ночной прогон ловит зависящее от времени и чужих сервисов.
3.3 Параллельность и её предел
Уровни 1 и 2 независимы — гоняй параллельно, сборку образа запускай вместе с линтером. Тесты дели по измеренному времени, а не по числу файлов: один интеграционный файл часто длиннее сотни юнитов, а смысл деления теряется, когда старт задачи сравним с куском работы (30–60 секунд).
3.4 Кеш зависимостей и когда он врёт
Ключ кеша — хеш lock-файла плюс версия рантайма и хеш базового образа: ключ по имени ветки значит, что после смены зависимостей установится старый набор.
Главный режим отказа: кеш скрывает сломанную установку — зависимость удалили из реестра, CI зелёный из кеша, а чистая сборка падает. Признак: «на CI собирается, у нового нет»; лечится ночным прогоном без кеша.
Кеш никогда не участвует в сборке релизного образа: он собирается из фиксированных версий с нуля.
4. Воспроизводимость сборки
«У меня собиралось» — почти всегда плавающие версии. Слоёв четыре.
- Зависимости: установка строго из lock-файла (
npm ci, а неnpm install). Быстрый шаг сверяет lock с манифестом: рассинхрон значит, что версии правили руками. - Рантайм: версия языка файлом в репозитории (
.python-version,.nvmrc,go.mod) — один источник для CI и локальной машины. - Базовый образ:
python:3.12-slim— движущаяся мишень: раз в неделю под ним другой набор системных библиотек. Фиксируй по digest, обновляй отдельным PR. - Сам конфиг CI: внешние шаги по плавающему тегу меняются под тобой — пини по коммиту.
Проверка: собери один коммит дважды с интервалом и сравни списки пакетов. Различаются — воспроизводимости нет, есть везение.
5. Секреты
5.1 Где хранить
По возрастанию зрелости: переменные CI с маскированием и ограничением на защищённые ветки → секреты платформы деплоя → менеджер секретов (Vault, KMS) с короткоживущими токенами.
Минимум: секретов нет в репозитории и в его истории; переменные недоступны прогонам из форков; у прода и стейджинга разные значения — один ключ платёжного шлюза на оба контура значит, что тестовый прогон может списать реальные деньги. Поиск секретов ставь pre-commit хуком: в CI он ловит поздно, коммит уже в истории.
5.2 Почему маскирование не защищает
Маскирование заменяет точное вхождение значения и проваливается предсказуемо:
- секрет напечатан по частям или изменённым (URL-кодирование, base64, обрезка);
- секрет внутри выведенной целиком структуры: дамп окружения,
set -x, трассировка со строкой подключения; - секрет ушёл не в лог, а в артефакт: отчёт тестов, HAR-файл, скриншот, дамп ответа API.
Отсюда: set -x в деплой-скриптах не включать никогда, артефакты прогона считать публичными. При утечке — ротировать, а не удалять лог: он уже прочитан и осел в резервных копиях.
5.3 Ротация
У каждого секрета есть владелец и запись «где выпускается, где применяется, где отзывается». Система обязана переживать две одновременно действующие версии ключа — иначе ротация равна простою и её будут откладывать. Уход сотрудника с доступом к CI — обязательный триггер замены.
6. Окружения и тестовые данные
Изолируется не только БД: своё объектное хранилище, очередь, ключи внешних API, отправитель писем и СМС, ключи подписи. Классическая авария первой настройки — стейджинг с прод-ключом рассылок отправил письма всей клиентской базе, потому что «это же тест». На нижних контурах запрещай исходящие вызовы наружу по умолчанию: тогда «случайно ушло в прод» технически невозможно, а не запрещено инструкцией.
6.1 Почему копия прода в стейджинге — утечка
Дамп прод-базы переносит персданные в контур, где доступ шире, защита слабее, а бэкапы никто не считает: обработка вне заявленных целей со всеми обязанностями оператора и без средств их исполнить. Плюс тестовое письмо уходит клиенту. Вместо дампа:
- Синтетика по схеме: правдоподобные ФИО, телефоны из диапазонов для вымышленных номеров, почта на
example.com, ИНН и карты, проходящие контрольную сумму, но не существующие. - Обезличивание при выгрузке, если нужны объём и распределение: маскируй до попадания в стейджинг, стабильной заменой, иначе связи между таблицами рассыплются. Оно слабое — «город + дата рождения + сумма заказа» часто восстанавливает личность.
И проверь, что на нижних контурах отключены реальные отправители писем и СМС, а эквайринг переведён на тестовые реквизиты.
7. Артефакты и версионирование образов
Артефакт собирается один раз и продвигается по контурам без пересборки: пересборка перед продом значит, что едет не то, что тестировали.
registry.example.ru/app/api:1.8.377
registry.example.ru/app/api:sha-9f1e445
registry.example.ru/app/api@sha256:...
Версия — для человека, коммит — для связи «что в проде с какой строкой кода», digest — для деплоя. Разворачивай по digest: тег можно перезаписать, digest — нет; latest в проде — прямая дорога к «откатились, а версия та же». Храни прод-образы 30 дней или 10 версий: политика очистки registry обнаруживается в момент, когда откат уже нужен.
8. Миграции БД в пайплайне
Миграция — единственный шаг деплоя, необратимый по данным: код откатывается подменой образа за секунды, удалённая колонка — только из бэкапа. Автоприменение при деплое опасно втройне: при откате кода схема остаётся новой; экземпляры гонятся за одной блокировкой; никто не читает SQL перед применением.
- На каждом PR — прогон на пустой базе и на копии структуры прода: ловит синтаксис и конфликты имён.
- Отдельная задача показывает сгенерированный SQL и затронутые таблицы с числом строк.
- Ручное подтверждение с фиксацией, кто подтвердил.
- Перед применением — свежий бэкап и проверка, что он читается, а не просто создан.
- Применение с таймаутом на блокировку: миграция, зависшая на блокировке активной таблицы, копит очередь и роняет сервис вернее, чем ошибка.
Правило совместимости: новая схема работает со старым кодом, иначе откат невозможен. Порядок: добавили nullable-колонку → код пишет в обе → заполнили данные → код читает новую → следующим релизом удалили старую.
Опасные операции: NOT NULL с проверкой, смена типа колонки, индекс без конкурентного режима, переименование — блокировка на время, пропорциональное размеру таблицы:
SELECT relname, n_live_tup, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC
LIMIT 20;
Миллион строк в затронутой таблице значит, что миграцию нельзя ставить в рабочие часы.
9. Проверки для внешних интеграций
- Контракт, а не мок. Мок ответа маркетплейса, написанный год назад, зелёный вечно и не значит ничего: держи записанные реальные ответы и ночной прогон против песочницы.
- Проверяй ключи до деплоя: «дёрнуть безобидный метод чтения каждым ключом» ловит истёкший токен за минуту, иначе он найдётся по нулю заказов за день.
- Вебхуки: свой публичный адрес на стейджинге, отдельная подпись, защита от повторов; тест идемпотентности (два одинаковых вебхука не создают два платежа).
- Привязка к IP. Ключ прод-сервера не работает с CI-раннера: нужен статический адрес раннера либо проверка с самого сервера после деплоя.
- Обмен с учётными системами. Выгрузки в 1С и обмен через МойСклад или Битрикс24 ломаются на кодировке, формате даты и разделителе дробной части — сверяй эталон побайтово.
10. Health-check: что он должен реально проверять
Эндпоинт, отдающий 200 OK без логики, проверяет одно: процесс жив и порт открыт, — и балансировщик держит инстанс в ротации, пока он с мёртвой БД отдаёт пятисотки. Нужны два эндпоинта.
- Liveness — «процесс не завис»: никаких внешних вызовов, ответ за единицы миллисекунд, отрицательный ответ означает перезапуск. Проверка БД здесь превратит недоступность базы в перезапуск всех экземпляров.
- Readiness — «экземпляр может обслуживать трафик сейчас»: БД (простейший запрос с таймаутом 1–2 секунды), очередь, обязательные переменные, применённость миграций. Отрицательный ответ выводит из балансировки без перезапуска.
Readiness не зависит от необязательных внешних сервисов: если проверка ходит в API маркетплейса, его плановые работы выведут из ротации весь сервис, хотя 90% функций работают. Их состояние — в диагностический эндпоинт для людей, не для балансировщика:
{
"status": "degraded",
"version": "1.8.377",
"checks": {
"db": {"ok": true, "latency_ms": 4},
"ozon_api": {"ok": false, "error": "timeout", "critical": false}
}
}
После настройки останови БД и убедись: liveness зелёный, readiness красный, трафик уведён. Health-check, не проверенный отключением зависимости, не проверен.
11. Логи и алерты без выгорания
Логи структурированные (JSON), одна запись — одно событие; поля: время, уровень, сервис, версия, идентификатор запроса и пользователя. Идентификатор запроса протаскивается через все сервисы — без него разбор инцидента станет сопоставлением по времени. Пароли, токены и тела запросов в логи не попадают; логи с персданными хранятся там же, где база.
Алерт оправдан при двух условиях: это видит пользователь и человек может что-то сделать сейчас. Остальное — дашборд или дайджест.
| Сигнал | Порог | Окно | Куда |
|---|---|---|---|
| Доля ответов 5xx | > 1% запросов | 5 минут подряд | Немедленно дежурному |
| Задержка p95 | вдвое выше обычной | 10 минут подряд | Немедленно дежурному |
| Недоступен снаружи | нет ответа | 2 проверки подряд | Немедленно дежурному |
Пороги стартовые — через две недели пересчитай по своим данным. Алерт, срабатывающий чаще раза в неделю без действий человека, чини или удаляй: пять ложных подряд — и настоящее проигнорируют. Против шума работают окно вместо мгновенного значения и группировка.
Отдельно алертай на бизнес-метрику: «ноль заказов за час днём» ловит сломанную интеграцию с маркетплейсом, когда техника зелёная — сервис исправно отвечает 200 на пустой список.
12. Типовые ошибки первой настройки
- Автоприменение миграций при деплое → откат кода невозможен, схема ушла вперёд.
- Один набор секретов на все контуры → тестовый прогон списывает деньги и шлёт СМС клиентам.
- Кеш по имени ветки → CI зелёный на старых зависимостях, чистая сборка падает.
- Дамп прода в стейджинге → персданные в слабозащищённом контуре и письмо реальному клиенту.
- Health-check вида
return "ok"→ балансировщик держит инстанс с мёртвой БД. - Деплой без ограничения одновременности → два прогона катят разные коммиты, побеждает финишировавший вторым.
- Прогон из форка получает прод-секреты → нужны защищённые переменные и запрет автозапуска внешних веток.
13. План внедрения для команды, которая деплоит руками
Ориентир — неделя на шаг; всё сразу не предлагай. Через месяц после последнего шага пересчитай пороги алертов и проверь восстановление из бэкапа.
- Записать текущий деплой скриптом, ничего не автоматизируя: уже здесь выясняется, что команды знает один человек и он в отпуске.
- Собрать артефакт в CI без деплоя: образ на каждый push, тег по коммиту, registry.
- Быстрые проверки на PR с целью 3 минуты; падающие из-за старого кода переводи в предупреждение, иначе отключат целиком.
- Стейджинг со своими данными: синтетика, ключи песочниц, запрет исходящих наружу, автодеплой на мерж в основную ветку.
- Секреты и окружения: вынести из конфигов, развести по контурам, назначить владельцев, провести первую ротацию.
- Миграции отдельным шагом: прогон в CI, показ SQL, ручное подтверждение, бэкап перед применением.
- Прод-деплой по кнопке: тот же артефакт со стейджинга, очередь на окружение, smoke-тест и записанный откат.
- Наблюдаемость: два эндпоинта health-check, структурированные логи, алерты из раздела 11, дежурный с именем.
План держи задачей с подзадачами через manage_task, решения — в documents. На выходе: таблица выбора площадки, карта данных, конфигурации CI и деплоя, реестр секретов без значений, таблица алертов, процедура отката.
14. Правила работы
- Не предлагай конфиг раньше, чем узнал стек, персданные и текущие ручные шаги: конфиг по угаданному стеку вреднее отсутствия.
- Не называй цены, тарифы и лимиты по памяти — проверь через
web_searchи поставь дату рядом с числом. - Не выдумывай номера законов и статей; где нужен юрист — так и скажи.
- Прежде чем отключать что-то в готовом пайплайне, спроси, зачем это добавили: у самой странной проверки обычно есть инцидент в анамнезе.
- Готовые файлы отдавай через
edit_fileи оформляй PR черезopen_pull_request: скопированный из чата конфиг теряет отступы, и первый прогон падает на невалидном YAML.
Similar skills
Try this skill
Sign up and use the "Настройка CI/CD" skill for free.