CI/CD для корпоративного ПО: как построить независимую инженерную платформу
Автор: Инженер-программист
Практическое руководство с примерами, расчётами и чек-листами
Почему CI/CD — это не про DevOps-моду, а про выживание
Реальный кейс:
Российский банк потратил 80 млн руб. на разработку системы управления рисками. Всё работало через GitLab Cloud и AWS. В марте 2022 — блокировка. Система встала. Данные недоступны. Восстановление с нуля заняло 4 месяца и ещё 35 млн руб.
Что пошло не так:
- CI/CD был в облаке вендора
- Артефакты хранились в Docker Hub
- Secrets в HashiCorp Cloud
- Документация в Confluence Cloud
Урок: Без собственной инженерной платформы нет контроля над продуктом.
Компании, которые начали с платформы, а не с продукта:
- Palantir: Собственная CI/CD с 2004 года, развёртывание в изолированных контурах
- Anduril: Полный цикл от сборки до деплоя на edge-устройства
- Яндекс: Собственная платформа разработки задолго до сервисов
Что такое CI/CD на практике (без воды)
CI (Continuous Integration) — конвейер качества
Что происходит при каждом коммите:
1. Commit → Git
↓
2. Trigger → CI-сервер активируется
↓
3. Checkout → Код загружается в чистое окружение
↓
4. Build → Сборка (Maven/Gradle/npm)
↓
5. Unit Tests → 500+ тестов за 2 минуты
↓
6. SAST → Сканирование уязвимостей (SonarQube)
↓
7. Dependency Check → Проверка библиотек
↓
8. Package → Создание артефакта (Docker image, JAR)
↓
9. Push → Артефакт в registry
↓
10. Report → Результаты в MR/PR
Время выполнения: 5–15 минут для среднего проекта.
Критерий успеха CI: Если pipeline зелёный — изменение безопасно интегрировать.
CD (Continuous Delivery/Deployment) — управляемая доставка
Два варианта:
Continuous Delivery (ручной релиз):
Артефакт готов → Одобрение → Деплой в staging →
Тестирование → Одобрение → Деплой в production
Continuous Deployment (автоматический релиз):
Артефакт готов → Автодеплой в staging →
Проверки пройдены → Автодеплой в production
Для корпоративных систем: Используют Continuous Delivery с обязательным одобрением для production.
Архитектура CI-сервера: минимум для старта
Железо и софт
Конфигурация CI-сервера (on-premise):
| Компонент | Требования | Стоимость |
|---|---|---|
| Сервер | 16 CPU, 64GB RAM, 1TB NVMe | 300–500 тыс. руб. |
| ОС | Ubuntu 22.04 LTS / RHEL 9 | Бесплатно / лицензия |
| GitLab CE/EE | Self-hosted | Бесплатно / от 500 тыс./год |
| Docker/Podman | Container runtime | Бесплатно |
| Registry | Harbor / GitLab Registry | Бесплатно |
| Мониторинг | Prometheus + Grafana | Бесплатно |
Итого на старт: 800 тыс.–1.5 млн руб. (единоразово) + 500 тыс.–1 млн руб./год на поддержку.
Базовая схема инфраструктуры
┌─────────────────────────────────────────┐
│ Разработчики (VPN) │
└────────────┬────────────────────────────┘
↓
┌────────────────────────────────────────┐
│ Git Server (GitLab on-prem) │
│ • Репозитории │
│ • MR/PR процесс │
│ • Webhooks → CI │
└────────────┬───────────────────────────┘
↓
┌────────────────────────────────────────┐
│ CI Server (GitLab Runner) │
│ • Executor: Docker │
│ • Pipeline выполнение │
│ • Артефакты → Registry │
└────────────┬───────────────────────────┘
↓
┌────────────────────────────────────────┐
│ Artifact Storage │
│ • Docker Registry (Harbor) │
│ • Maven/npm Repository (Nexus) │
└────────────┬───────────────────────────┘
↓
┌────────────────────────────────────────┐
│ Environments │
│ • Staging (auto-deploy) │
│ • Production (manual approval) │
└─────────────────────────────────────────┘
Pipeline как код: пример из реальной жизни
Задача: Java-приложение с PostgreSQL
Файл .gitlab-ci.yml (упрощённый):
yaml
stages:
- build
- test
- security
- package
- deploy
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
build:
stage: build
image: maven:3.9-eclipse-temurin-17
script:
- mvn clean compile
cache:
paths:
- .m2/repository
only:
- main
- merge_requests
unit-tests:
stage: test
image: maven:3.9-eclipse-temurin-17
script:
- mvn test
artifacts:
reports:
junit: target/surefire-reports/TEST-*.xml
coverage: '/Total.*?([0-9]{1,3})%/'
integration-tests:
stage: test
image: maven:3.9-eclipse-temurin-17
services:
- postgres:15
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test
POSTGRES_PASSWORD: test
script:
- mvn verify -Pintegration-tests
security-scan:
stage: security
image: sonarqube:community
script:
- sonar-scanner -Dsonar.projectKey=$CI_PROJECT_NAME
only:
- main
dependency-check:
stage: security
image: owasp/dependency-check:latest
script:
- dependency-check.sh --project "$CI_PROJECT_NAME" --scan .
artifacts:
paths:
- dependency-check-report.html
package:
stage: package
image: docker:24
services:
- docker:24-dind
script:
- docker build -t $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA .
- docker tag $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
$CI_REGISTRY/$CI_PROJECT_PATH:latest
- docker push $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
- docker push $CI_REGISTRY/$CI_PROJECT_PATH:latest
only:
- main
deploy-staging:
stage: deploy
image: alpine:latest
script:
- apk add --no-cache openssh
- ssh deploy@staging "docker pull $CI_REGISTRY/$CI_PROJECT_PATH:latest"
- ssh deploy@staging "docker-compose up -d"
environment:
name: staging
url: https://staging.example.com
only:
- main
deploy-production:
stage: deploy
image: alpine:latest
script:
- ssh deploy@prod "docker pull $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA"
- ssh deploy@prod "docker-compose up -d"
environment:
name: production
url: https://example.com
when: manual
only:
- main
Что делает этот pipeline:
- Собирает Java-приложение
- Прогоняет unit-тесты (500+ тестов)
- Запускает интеграционные тесты с PostgreSQL
- Сканирует код на уязвимости (SAST)
- Проверяет зависимости (OWASP)
- Собирает Docker-образ
- Автоматически деплоит в staging
- Деплоит в production по кнопке
Время выполнения: 8–12 минут.
Main-ветка: точка максимального контроля
Правила работы с main
Запреты:
- Прямой push в main
- Force push
- Коммиты без issue/task ID
- Merge без прохождения CI
Обязательные проверки перед merge:
- CI pipeline успешен
- Code review от минимум 2 человек
- Тесты покрывают изменения
- Документация обновлена (если нужно)
Настройка в GitLab:
yaml
# .gitlab/merge_request_templates/Default.md
## Описание
<!-- Что изменено и зачем -->
## Чек-лист
- [ ] Тесты добавлены/обновлены
- [ ] Документация обновлена
- [ ] CI pipeline зелёный
- [ ] Нет breaking changes (или они задокументированы)
## Связанные issue
Closes #123
```
**Protected branches settings:**
- Allowed to merge: Maintainers
- Allowed to push: Nobody
- Require approval: 2 reviewers
- Require passing pipeline: Yes
---
## Безопасность: VPN, ключи и секреты
### Схема доступа к Git-серверу
```
Разработчик → VPN → GitLab (on-prem)
↓
SSH-ключ (Ed25519)
↓
2FA (обязательно)
Настройка SSH-ключа:
bash
# Генерация ключа
ssh-keygen -t ed25519 -C "developer@company.com"
# Добавление в SSH-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Добавление в GitLab
cat ~/.ssh/id_ed25519.pub
# Копировать в GitLab → Settings → SSH Keys
Управление секретами
Плохо (так делать нельзя):
yaml
# .gitlab-ci.yml
script:
- export DB_PASSWORD="super_secret_123" # ❌ НИКОГДА
Правильно:
yaml
# GitLab → Settings → CI/CD → Variables
# Добавить: DB_PASSWORD (masked, protected)
# .gitlab-ci.yml
script:
- echo "Connecting to DB..."
- java -jar app.jar --db.password=$DB_PASSWORD
Для production секретов: HashiCorp Vault (self-hosted) или GitLab-integrated secrets.
GitLab vs GitHub: что выбрать
Сравнительная таблица
| Критерий | GitLab (on-prem) | GitHub Enterprise |
|---|---|---|
| Автономность | Полная | Частичная |
| Контроль данных | 100% | Зависит от контракта |
| Встроенный CI/CD | Из коробки | Actions (cloud-first) |
| Registry | Встроенный | Отдельно GHCR |
| Стоимость (500 юзеров) | 2–3 млн/год | 4–6 млн/год |
| Кастомизация | Полная | Ограничена |
| Блокировка рисков | Отсутствуют | Возможны санкции |
Рекомендация
Для корпоративного ПО:
GitLab CE/EE (self-hosted) — стратегически устойчивее.
Для open-source проектов:
GitHub — больше комьюнити, лучше для публичных репозиториев.
Путь от нуля до инженерной платформы (6 месяцев)
Месяц 1: Фундамент
Инфраструктура:
- Поднять GitLab on-prem
- Настроить VPN-доступ
- Развернуть CI-сервер (GitLab Runner)
- Настроить Docker Registry
Команда:
- Обучить разработчиков Git Flow
- Провести workshop по CI/CD
- Назначить ответственных за инфраструктуру
Месяц 2–3: Первые пайплайны
Технические задачи:
- Написать базовый pipeline для 2–3 проектов
- Настроить автоматические тесты
- Внедрить SAST (SonarQube)
- Настроить staging-среду
Процессы:
- Зафиксировать правила работы с main
- Внедрить code review как обязательный этап
- Создать шаблоны MR
Месяц 4–5: Зрелость
Автоматизация:
- Автодеплой в staging
- Ручной деплой в production
- Rollback процедуры
- Мониторинг пайплайнов (Grafana)
Безопасность:
- Настроить Vault для секретов
- Ротация ключей
- Audit logs
Месяц 6: Масштабирование
Команда:
- Документировать все процессы
- Создать runbook для инцидентов
- Внедрить метрики (DORA, lead time)
- Подключить оставшиеся проекты
Результат: Полностью контролируемая инженерная платформа.
Метрики: как измерить зрелость CI/CD
DORA метрики (DevOps Research and Assessment)
| Метрика | Начальный уровень | Зрелый уровень |
|---|---|---|
| Deployment Frequency | 1 раз в месяц | Несколько раз в день |
| Lead Time for Changes | 1–6 месяцев | < 1 дня |
| Change Failure Rate | 46–60% | 0–15% |
| Time to Restore | 1 неделя–1 месяц | < 1 часа |
Дополнительные метрики
Для команды:
- Время выполнения pipeline (цель: < 15 мин)
- % успешных пайплайнов (цель: > 90%)
- Покрытие тестами (цель: > 70%)
Для бизнеса:
- Time-to-market для фич (цель: < 2 недель)
- Количество инцидентов после релиза (цель: < 5%)
Антипаттерны CI/CD
Антипаттерн 1: CI на dev-машинах
Проблема:
«У меня работает» — потому что окружение уникально.
Решение:
Чистое окружение для каждого запуска (Docker/Kubernetes).
Антипаттерн 2: Секреты в коде
Проблема:
Пароли и ключи в репозитории = утечка данных.
Решение:
Vault, GitLab CI/CD Variables, AWS Secrets Manager (self-hosted).
Антипаттерн 3: Пайплайны на 2 часа
Проблема:
Разработчики перестают ждать результатов CI.
Решение:
Параллелизация, кэширование, оптимизация тестов.
Антипаттерн 4: Ручной деплой с ноутбука
Проблема:
«Только я знаю, как задеплоить» = bus factor = 1.
Решение:
Деплой только через CI/CD, кнопка для production.
Экономика: почему платформа окупается
Расчёт на 5 лет (команда 20 разработчиков)
Без CI/CD (ручные процессы):
| Статья | Год 1 | Год 2–5 | Итого |
|---|---|---|---|
| Ручное тестирование | 3 млн | 3 млн/год | 15 млн |
| Инциденты на production | 2 млн | 2 млн/год | 10 млн |
| Простои при деплое | 1 млн | 1 млн/год | 5 млн |
| Всего | 6 млн | 6 млн/год | 30 млн |
С CI/CD платформой:
| Статья | Год 1 | Год 2–5 | Итого |
|---|---|---|---|
| Внедрение платформы | 5 млн | — | 5 млн |
| Поддержка | 1 млн | 1 млн/год | 5 млн |
| Инциденты (снижение на 80%) | 400 тыс. | 400 тыс./год | 2 млн |
| Всего | 6.4 млн | 1.4 млн/год | 12 млн |
Экономия: 18 млн руб. (60%) за 5 лет.
Главные принципы
- CI/CD — это не инструмент, а дисциплина: Без правил работы платформа бесполезна.
- Автономность критична: On-premise инфраструктура = отсутствие vendor lock-in.
- Pipeline — это бизнес-процесс: Формализуйте через код, а не документы.
- Безопасность с первого дня: VPN, SSH-ключи, Vault для секретов.
- Начинайте с малого: 1 проект → pipeline → масштабирование на всю команду.
Главная мысль:
Компании, которые владеют инженерной платформой, владеют своим будущим. CI/CD — первый шаг к технологическому суверенитету.
