# Runbook: деплой F-1 (CVE vendor-апдейт) на боевой liderra.ru

> Тип: deploy-runbook (положен в plans/, т.к. свободная запись стены — только specs/plans).
> **Исполняет ВЛАДЕЛЕЦ в своём терминале** (прод-ops под стеной не идут). Деплой НЕОБРАТИМ —
> сначала прогнать pre-flight и сделать бэкап. Все команды — через `ssh liderra-prod`.
> **Пути ниже — проверить под свой прод** (ожидается приложение в `/var/www/liderra/app`,
> пользователь `www-data`).

## Что деплоим и зачем

F-1 (tech-audit 15.06): 14 CVE на 9 пакетах. Локально уже пропатчено (`composer.lock`):
`laravel/framework v13.15.0`, `guzzlehttp/psr7 2.11.0`, symfony 7.4-патченые. Прод крутит
уязвимые версии (vendor не пересобран). App-код прод↔main в паритете (сверено хешами) →
деплой узкий: **обновить зависимости на проде**, код не выкатываем.

Переменные (подставить свои):

```
PROD_APP=/var/www/liderra/app        # корень Laravel-приложения на проде
PROD_USER=www-data                   # владелец файлов приложения
```

## 0. Pre-flight (read-only, ничего не меняет)

```bash
# здоровье сервера
ssh liderra-prod 'df -h /'                                   # диск: должно быть >2-3 ГБ свободно
ssh liderra-prod 'systemctl is-active nginx php8.3-fpm postgresql liderra-queue'

# ТЕКУЩИЕ (уязвимые) версии на проде — зафиксировать ДО деплоя
ssh liderra-prod 'cd /var/www/liderra/app && composer show laravel/framework guzzlehttp/psr7 symfony/yaml symfony/http-foundation 2>/dev/null | grep -E "name|versions"'
ssh liderra-prod 'cd /var/www/liderra/app && composer audit --locked --no-interaction || true'

# зафиксировать точку отката (git)
ssh liderra-prod 'cd /var/www/liderra/app && git rev-parse HEAD'
```

Критерий GO для деплоя: диск ОК, службы active, версии на проде — старые (есть смысл патчить),
`composer audit` показывает те же advisories.

## 1. Бэкап (точка отката ДО изменений)

```bash
ssh liderra-prod 'cd /var/www/liderra/app && sudo cp composer.lock composer.lock.bak-f1 && sudo tar czf /var/www/liderra/vendor-bak-f1.tar.gz vendor'
ssh liderra-prod 'ls -lh /var/www/liderra/vendor-bak-f1.tar.gz'
```

## 2. Доставка пропатченного composer.lock

Цель: на проде должен оказаться локальный (пропатченный) `composer.lock`. Способы (выбрать
рабочий по факту):

- **git** (если прод-репо чист и main доступен): `ssh liderra-prod 'cd /var/www/liderra/app && sudo -u www-data git fetch && sudo -u www-data git checkout origin/main -- composer.lock'`
- **scp** (если проще файлом): `scp app/composer.lock liderra-prod:/tmp/composer.lock` → `ssh liderra-prod 'sudo cp /tmp/composer.lock /var/www/liderra/app/composer.lock && sudo chown www-data:www-data /var/www/liderra/app/composer.lock'`

Проверить, что lock доставлен (laravel должен стать v13.15.0):

```bash
ssh liderra-prod 'cd /var/www/liderra/app && grep -A1 "\"name\": \"laravel/framework\"" composer.lock | grep version'
```

## 3. Обновление vendor (главный шаг)

```bash
ssh liderra-prod 'cd /var/www/liderra/app && sudo -u www-data composer install --no-dev --optimize-autoloader --no-interaction'
```

> `install` (не `update`) — ставит ровно версии из доставленного lock, без дрейфа.
> `--no-dev` — прод без dev-зависимостей. После — при необходимости `php artisan optimize:clear`.

## 4. Smoke-проверка (признак успеха)

```bash
ssh liderra-prod 'cd /var/www/liderra/app && composer audit --locked --no-interaction'   # ЦЕЛЬ: no advisories
ssh liderra-prod 'cd /var/www/liderra/app && composer show laravel/framework | grep versions'  # v13.15.0
ssh liderra-prod 'cd /var/www/liderra/app && sudo -u www-data php artisan about | head -30'
ssh liderra-prod 'curl -sS -o /dev/null -w "%{http_code}\n" https://liderra.ru/'           # 200/302
ssh liderra-prod 'sudo journalctl -u liderra-queue --since "5 min ago" --no-pager | tail -20'  # без фатальных
```

Критерий приёмки: `composer audit` БЕЗ advisories, портал отвечает, очередь без новых
фатальных ошибок.

## 5. Откат (если smoke провалился)

```bash
ssh liderra-prod 'cd /var/www/liderra/app && sudo cp composer.lock.bak-f1 composer.lock && sudo rm -rf vendor && sudo tar xzf /var/www/liderra/vendor-bak-f1.tar.gz -C /var/www/liderra/app && sudo chown -R www-data:www-data vendor composer.lock'
ssh liderra-prod 'cd /var/www/liderra/app && sudo -u www-data php artisan optimize:clear'
```

После успешного деплоя (через сутки стабильности) бэкап можно убрать:
`ssh liderra-prod 'rm -f /var/www/liderra/vendor-bak-f1.tar.gz /var/www/liderra/app/composer.lock.bak-f1'`

## Gate

- Запуск — **только с явного «деплоим»** от владельца.
- Перед п.3 желательно прогнать `prod-deploy-validator` (GO/NO-GO) — отдельно, в терминале.
- Если на проде нет миграций lead-region (маловероятно — фича live) — это другой деплой, не этот.

## Связанное

- Находки: `docs/superpowers/audits/2026-06-15-portal-tech-audit-findings.md` (F-1).
- Прод-паритет/доступ: `docs/superpowers/audits/2026-06-15-prod-vs-local-snapshot.md`,
  память `project-gitea-backup-prod-access` (`ssh liderra-prod`).
- Прочие хвосты на потом: F-2 (a11y Tenants), F-3 (pint/format), F-5 (md-lint), F-T2 harden
  (блок Б-1/DO-4).
