architect/standards/arch-deployment-operation.md

type: standard
layer: arch
object: deployment
aspect: operation
form: text
title: "Операция ДЕПЛОЙ"
status: active
version: 1.0.0
date: 2026-04-11
knowledge_level: У1
parent: arch-platform-policy.md
deps:
- arch-platform-policy.md
- arch-security-policy.md
- arch-component-structure.md


Операция ДЕПЛОЙ

Стандарт описывает операцию ДЕПЛОЙ — запуск сервисов и компонентов в рабочее окружение. Все сервисы только через Docker Compose (П3 СЕРВИСЫ). Деплой в prod — только после явного "да" оператора (L4).


1. ОКРУЖЕНИЯ

Окружение Назначение Ветка git Уровень
local Разработка любая L2
dev Интеграция feature/* L2
staging Предпрод, QA main L3
prod Production main (теги) L4

Правило: prod только после staging. Деплоить в prod минуя staging — нарушение политики.


2. СТРУКТУРА СЕРВИСА

Каждый деплоймент — компонент типа .service или .ui:

infra/@{имя}.service/
├── AI.md                  ← роль, правила
├── CLAUDE.md              ← навигация
├── index.yaml             ← class: ServiceComponent
├── docker-compose.yml     ← точка входа
├── .env.example           ← переменные без значений
└── config/                ← конфиги сервиса

.env с реальными значениями — в $DATASPACE, не в git.


3. ПРОТОКОЛ ДЕПЛОЯ

Шаг 1 — Проверка ресурсов

bash /opt/scripts/check_resources.sh
# GREEN → продолжай / YELLOW → cleanup / RED → СТОП

Шаг 2 — Метка отката

# пометить текущую версию
docker tag {service}:latest {service}:backup-$(date +%Y%m%d-%H%M)
git branch backup/$(date +%Y%m%d-%H%M)

Шаг 3 — Получить актуальный код

git pull origin main
# или для конкретной ветки:
git checkout feature/my-feature && git pull

Шаг 4 — Собрать образ

cd infra/@{имя}.service/
docker compose build --no-cache

Шаг 5 — Применить миграции БД (если есть)

docker compose run --rm app alembic upgrade head
# проверить:
docker compose run --rm app alembic current

Шаг 6 — Запустить

docker compose up -d

Шаг 7 — Проверить

# статус контейнеров
docker compose ps

# health check
curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}/health
# ожидаем: 200

# логи первых 30 секунд
docker compose logs --tail=50 -f app &
sleep 30 && kill %1

Шаг 8 — Отчёт

ЗАДЕПЛОЕНО:
 Сервис: {имя}
 Окружение: {dev/staging/prod}
 Версия: {git commit hash}
 Статус: 200 OK
ОТКАТ: docker tag {service}:backup-{date} {service}:latest && docker compose up -d

4. ДЕПЛОЙ В PROD (L4)

Обязательные условия перед prod:

✅  Прошло staging
✅  QA проверено
✅  Бэкап БД сделан
✅  .env для prod — актуален
✅  Оператор явно написал "деплоим в прод"

Запрос подтверждения:

⚠️ L4 ДЕПЛОЙ В PROD
Сервис: {имя}
Версия: {hash}
Бэкап БД: СДЕЛАН ✅
Откат: docker rollback + pg_restore

Напиши явно "да" для продолжения.

5. NGINX (реверс-прокси)

Nginx — системный компонент, единственное исключение из правила Docker для сервисов.

Добавить новый сервис

# /etc/nginx/sites-available/{домен}.conf
server {
    listen 80;
    server_name {домен};

    location / {
        proxy_pass http://localhost:{port};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
ln -s /etc/nginx/sites-available/{домен}.conf /etc/nginx/sites-enabled/
nginx -t && nginx -s reload

Проверка после изменения nginx

nginx -t                                              # синтаксис
curl -s -o /dev/null -w "%{http_code}" http://{домен}  # статус

6. CRON-ЗАДАЧИ

Cron только через system/scheduler/ — не через crontab -e напрямую.

# system/scheduler/tasks/{имя}.yaml
id: nocodb-backup
schedule: "0 3 * * *"
command: bash /opt/scripts/backup-nocodb.sh
service: nocodb
on_failure: notify_telegram

7. ОТКАТ

При сбое деплоя → немедленно откатить, не продолжать диагностику в prod.

Матрица откатов

Что упало Метод отката Команды Время
Docker-сервис предыдущий образ см. ниже ~5 мин
База данных (PostgreSQL) восстановление из дампа см. ниже ~30 мин
Alembic-миграция alembic downgrade см. ниже ~2 мин
Drupal обновление drush updb --rollback см. ниже ~5 мин
Nginx конфиг предыдущий конфиг из git см. ниже ~2 мин
Docker volume с данными восстановление из tar-архива см. ниже ~15 мин
Git коммит в код git revert см. ниже ~5 мин

Docker-сервис

# пометить ПЕРЕД деплоем (делается в §3 Шаг 2)
docker tag {service}:latest {service}:backup-$(date +%Y%m%d-%H%M)

# откат
docker compose down
docker tag {service}:backup-YYYYMMDD-HHmm {service}:latest
docker compose up -d

# проверка
docker compose ps
curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}/health

База данных (PostgreSQL)

# 1. остановить сервис
docker compose stop app

# 2. восстановить из дампа
gunzip -c $DATASPACE/backups/db/YYYYMMDD_HHmm_pre-deploy.sql.gz | \
  psql -U $DB_USER -d $DB_NAME

# 3. проверить
psql -U $DB_USER -d $DB_NAME -c "SELECT COUNT(*) FROM key_table;"

# 4. запустить
docker compose start app

Alembic (Python миграции)

# посмотреть текущую версию
docker compose run --rm app alembic current

# откат на 1 версию назад
docker compose run --rm app alembic downgrade -1

# откат до конкретной ревизии
docker compose run --rm app alembic downgrade {revision_id}

# проверка
docker compose run --rm app alembic current

Drupal (PHP миграции)

# посмотреть статус модулей
docker compose exec app drush pm-list --status=enabled

# откат последнего обновления через drush
docker compose exec app drush updb --rollback

# если не помогло — восстановить БД из дампа (см. PostgreSQL)

Nginx конфиг

# откат через git
git checkout HEAD -- /etc/nginx/sites-available/{домен}.conf
nginx -t && nginx -s reload

# проверка
curl -s -o /dev/null -w "%{http_code}" https://{домен}/

Docker Volume с данными

# восстановить volume из архива
docker compose stop app
docker run --rm \
  -v {volume_name}:/data \
  -v $DATASPACE/backups/volumes:/backup \
  alpine sh -c "cd /data && tar xzf /backup/YYYYMMDD_HHmm_vol_{name}.tar.gz"
docker compose start app

Git коммит

# безопасный откат (создаёт новый коммит)
git revert HEAD

# откат к конкретному коммиту
git revert {commit-hash}

# проверить
git log --oneline -5

Запрещено: git reset --hard в main без явного "да" оператора (L4).

Порядок действий при инциденте

1. СТОП  остановить все изменения
2. ОЦЕНИТЬ  что именно сломалось (код / данные / конфиг)
3. ВЫБРАТЬ метод из матрицы выше
4. УВЕДОМИТЬ оператора перед откатом БД (L4)
5. ОТКАТИТЬ  выполнить команды
6. ПРОВЕРИТЬ  сервис отвечает, данные целы
7. ЗАФИКСИРОВАТЬ  system/monitor/alerts/CRITICAL/

Полный протокол безопасности: arch-security-policy.md — §4 С3: ОТКАТ.


8. ОЧИСТКА ДИСКА

Три уровня

L0 → Автоматическая (monitor при disk >= 90%) — безопасно, без уведомления
L1 → С подтверждением (вручную или при disk >= 95%) — умеренный риск
L2 → Только вручную через SSH (критическая ситуация) — удаляет prod данные

L0 — Безопасная (100–500 MB)

find /tmp -type f -mtime +7 -delete
apt-get clean -y
docker image prune -f && docker volume prune -f
journalctl --vacuum-size=500M
find /var/log -name "*.gz" -mtime +7 -delete

L1 — Средняя (3–8 GB, требует подтверждения)

docker system prune -a --volumes -f
find $INFRA/backups -type f -mtime +30 -delete
find $WORKSPACE -name "node_modules" -type d -mtime +60 -exec rm -rf {} \;
git gc --aggressive

L2 — Опасная (10–20 GB, только SSH)

Удаляет: все Docker образы, неиспользуемые БД, old бэкапы.
Обязателен бэкап L4 перед выполнением.

Disk audit

df -h /                          # общий % диска
du -sh $WORKSPACE/* | sort -hr | head -10   # топ папок
docker system df                 # Docker потребление

9. СВЯЗАННЫЕ ДОКУМЕНТЫ