# DEV TASK — ORCH-34: хост-деплой-хук orchestrator с health-чеком и авто-rollback **Проект:** orchestrator | **Сервер:** slin@82.22.50.71 (pw motoZ@yaz2010) | **Репо:** /home/slin/repos/orchestrator **Ветка:** `feature/ORCH-34-deploy-hook` из свежего origin/main. `git fetch origin && git checkout main && git pull --ff-only && git checkout -b feature/ORCH-34-deploy-hook`. **Этап:** 4 из 5 (после Этапов 1-3: staging живой на 8501, песочница рабочая, тест-сьют в main). ## ЦЕЛЬ Написать деплой-хук `scripts/orchestrator-deploy-hook.sh` — bash-скрипт, который продвигает (промоутит) orchestrator на новый образ С HEALTH-ЧЕКОМ и АВТОМАТИЧЕСКИМ ОТКАТОМ, если новый контейнер не поднялся. Это аналог `/home/slin/bin/enduro-deploy-hook.sh`, НО с обязательным health-циклом + auto-rollback (которого у enduro-хука НЕТ). ⚠️ **ВАЖНО ПРО БЕЗОПАСНОСТЬ:** на Этапе 4 хук тестируется ТОЛЬКО на STAGING-контейнере (`orchestrator-staging`, порт 8501). Боевой прод (`orchestrator`, 8500) хук на этом этапе НЕ ТРОГАЕТ. Поэтому скрипт ДОЛЖЕН быть параметризован по цели (service name + порт health) через аргументы/env, дефолт — БЕЗОПАСНЫЙ (staging), а не прод. Переключение на прод — осознанный шаг Этапа 5 / ручной запуск Славой, НЕ в этом ТЗ. ## ОБРАЗЕЦ (изучить, повторить паттерн PREV_IMG) `/home/slin/bin/enduro-deploy-hook.sh` (прочитай его на хосте). Из него берём: - режим `--rollback`: восстановить образ из `$PREV_IMAGE_FILE` (retag PREV_IMG → APP_IMAGE, `docker compose up -d --no-build`), если файла нет — exit !=0. - normal deploy: захватить ТЕКУЩИЙ образ контейнера ДО рестарта в `$PREV_IMAGE_FILE` (best-effort, не падать), `git pull`, `docker compose up -d`. - логирование с UTC-таймстампами в лог-файл. ## ЧЕГО У ОБРАЗЦА НЕТ И ЧТО ДОБАВИТЬ (суть ORCH-34) После рестарта целевого контейнера — **HEALTH-ЦИКЛ**: опрашивать `http://localhost:/health` **10 попыток × 6 секунд = до 60с**. Критерий успеха: HTTP 200 И тело содержит `"status":"ok"`. - Если health стал ok в пределах 60с → деплой успешен, exit 0. - Если за 60с health НЕ поднялся → **АВТОМАТИЧЕСКИЙ ROLLBACK**: вызвать собственную rollback-ветку (восстановить PREV_IMG, рестарт, и ещё раз health-чек восстановленного — короткий, напр. 5×3с). Залогировать «deploy FAILED, rolled back to PREV_IMG». exit !=0 (чтобы вызывающий конвейер знал о фейле). - Если и после rollback health не поднялся → залогировать критично «ROLLBACK ALSO FAILED», exit !=0. ## ПАРАМЕТРИЗАЦИЯ (обязательно — для безопасности) Скрипт принимает (через env-переменные с дефолтами ИЛИ флаги — на твоё усмотрение, задокументируй): - `TARGET_SERVICE` (имя docker-compose сервиса) — **дефолт `orchestrator-staging`** (НЕ прод!). - `TARGET_PORT` (порт health) — **дефолт `8501`** (staging). - `TARGET_IMAGE` (образ для retag при rollback) — дефолт образа staging (узнай реальный: `docker inspect orchestrator-staging --format '{{.Config.Image}}'`). - `COMPOSE_PROFILE` — для staging нужен профиль `staging` (иначе compose не видит сервис). Учти: `docker compose --profile staging up -d --no-build `. - `PREV_IMAGE_FILE` — отдельный файл для staging (напр. `$REPO/.deploy-prev-image-staging`), чтобы НЕ пересекаться с прод-файлом enduro/орка. - `LOG` — отдельный лог (напр. `/var/log/orchestrator/deploy-hook.log`, создать каталог; если нет прав — fallback в `$REPO/deploy-hook.log`). - режимы: `--deploy` (дефолт, можно без флага) и `--rollback`. ⚠️ Прод-значения (service `orchestrator`, порт 8500, образ `orchestrator-orchestrator`) скрипт ПОДДЕРЖИВАЕТ через переопределение env, но ДЕФОЛТ — staging. В коде НЕ хардкодить прод как дефолт. ## ⛔ OFF-LIMITS / ПРАВИЛА - НЕ трогать src/, tests/, docker-compose.yml, .env, .env.staging, существующий `/home/slin/bin/enduro-deploy-hook.sh`. Только НОВЫЙ файл `scripts/orchestrator-deploy-hook.sh` + `docs/DEPLOY_HOOK.md` (как работает, переменные, примеры запуска для staging И прода). - Тестировать ТОЛЬКО на `orchestrator-staging` (8501). Боевой прод `orchestrator` (8500) НЕ рестартить, НЕ трогать. Если тест может задеть прод — СТОП, отчёт. - НЕ менять `DEPLOY_HOOK_SCRIPT` в .env прода (переключение хука — Этап 5, не сейчас). - НЕ регистрировать раннеров, НЕ nohup долгих процессов. Раннер mva154-runner-orch уже есть. - PR push в main ЗАПРЕЩЁН. НЕ мержить — коммит в ветку + PR. - Если факт разошёлся с ТЗ — СТОП, отчёт, не угадывать. ## ПРОВЕРКА (обязательный пруф в отчёт) — всё на STAGING Скрипт лежит в репо (`scripts/`), но для теста его надо запускать НА ХОСТЕ (он дёргает docker compose). Тестовый прогон: 1. **Happy-path:** запустить хук в `--deploy` против staging (TARGET_SERVICE=orchestrator-staging, PORT=8501, profile staging). Показать лог: захват PREV_IMG → рестарт → health стал ok за N секунд → exit 0. После — `curl localhost:8501/health` = ok. 2. **Rollback-path (САМОЕ ВАЖНОЕ):** сэмулировать НЕработающий деплой и доказать авто-откат. Безопасный способ: запустить хук с заведомо «битым» образом ИЛИ временно подменить health-цель на несуществующий порт, чтобы health-цикл провалился → хук должен сам откатиться на PREV_IMG и поднять staging обратно. Показать лог: «health failed after 60s → ROLLBACK → restored PREV_IMG → staging ok again», exit !=0. ПОСЛЕ теста staging ОБЯЗАН быть жив (`curl localhost:8501/health` = ok). Опиши ТОЧНО, как симулировал фейл (чтобы воспроизводимо и без риска проду). 3. **Прод не задет:** `curl localhost:8500/health` = ok, `docker ps` показывает прод `orchestrator` Up без рестарта (сравни uptime до/после). 4. `git log --oneline origin/main..origin/feature/ORCH-34-deploy-hook` — коммит виден ПОСЛЕ push. ⚠️ Если для rollback-теста придётся пересобирать/портить staging-образ — делай это ОБРАТИМО и в самом конце верни staging в рабочее состояние (health ok). НЕ оставляй staging сломанным. ## РЕЗУЛЬТАТ Новые файлы: `scripts/orchestrator-deploy-hook.sh` (deploy + rollback + health-цикл 10×6с + auto-rollback, параметризован, дефолт staging) + `docs/DEPLOY_HOOK.md`. Оба тест-прогона (happy + rollback) зелёные на staging, прод цел. PR в Gitea. Отчёт → `tasks/orchestrator/reports/dev-2026-06-05-orch34-deploy-hook.md`. Коммит: `feat(staging): add orchestrator deploy hook with health-check and auto-rollback (ORCH-34)`.