Перейти к содержанию

Runbook — восстановление автодеплоя alatyr-taverna

Задача 30 · 07.08.2026 · Что делает пользователь один раз, чтобы автодеплой заработал

Что готово агентом

  • skeletons/deploy-taverna.yml — production-ready workflow (build на VPS, консистентно с alatyr-service)

Модель деплоя

"Pull-on-server" — GitHub Actions по SSH командует VPS сделать git pull + npm ci + npm run build + rsync + reload nginx. Не билдим в Actions, не копируем 300 МБ dist через сеть.

Плюсы vs старая модель "build-in-actions + rsync": - Быстрее (нет upload/download артефактов) - Идентично работающему alatyr-service - Актуальный коммит на VPS явно виден в git log

Шаг 1: подготовить VPS (5 минут)

Установить git checkout, если его нет:

# от юзера oswold на VPS
cd ~
if [ ! -d alatyr-taverna ]; then
    git clone git@github.com:oswold1979/alatyr-taverna.git
fi
cd alatyr-taverna
git remote -v  # должен показать git@github.com:oswold1979/alatyr-taverna.git

# Проверить что npm/node в PATH
node --version   # должен быть 20+
npm --version

Если Node нет — установить через nvm или apt:

sudo apt install -y nodejs npm
# или через nvm (лучше для контроля версий):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Шаг 2: настроить sudoers для nginx reload (одна строка)

sudo tee /etc/sudoers.d/oswold-deploy-taverna <<'EOF'
oswold ALL=(root) NOPASSWD: /usr/sbin/nginx -t, /bin/systemctl reload nginx, /usr/bin/rsync -a --delete /home/oswold/alatyr-taverna/dist/ /opt/alatyr/dist/
EOF
sudo chmod 440 /etc/sudoers.d/oswold-deploy-taverna
sudo visudo -c  # проверка синтаксиса

Внимание: список команд в sudoers должен точно совпадать с тем что вызывает workflow. Если поменяешь VPS_DIST_PATH — поправь и sudoers.

Шаг 3: SSH-ключ для GitHub Actions (deploy key)

Создать отдельный ключ только для деплоя:

# на VPS от oswold
ssh-keygen -t ed25519 -f ~/.ssh/deploy_taverna -C "github-actions@alatyr-taverna" -N ""

# добавить публичную часть в authorized_keys
cat ~/.ssh/deploy_taverna.pub >> ~/.ssh/authorized_keys

# показать приватный ключ (скопировать всё, включая BEGIN/END)
cat ~/.ssh/deploy_taverna

Скопируй приватный ключ в буфер обмена — он пойдёт в GitHub Secret VPS_SSH_KEY.

Шаг 4: known_hosts

# С любой машины (не с VPS!)
ssh-keyscan -H 46.17.99.183 2>/dev/null

Скопируй вывод (2-3 строки) — пойдёт в VPS_KNOWN_HOSTS.

Шаг 5: GitHub Secrets

В браузере: https://github.com/oswold1979/alatyr-taverna/settings/secrets/actionsNew repository secret.

Создать 6 секретов:

Name Value
VPS_SSH_KEY приватный ключ из шага 3 (весь блок с BEGIN/END)
VPS_KNOWN_HOSTS вывод из шага 4
VPS_USER oswold
VPS_HOST 46.17.99.183
VPS_PATH /home/oswold/alatyr-taverna
VPS_DIST_PATH /opt/alatyr/dist

Шаг 6: скопировать workflow в репо

# на твоём Windows/локальной машине
cd ~/dev/alatyr-taverna   # где у тебя клон
mkdir -p .github/workflows

Скопируй skeletons/deploy-taverna.yml из alatyr-infra-kb в .github/workflows/deploy.yml. Через VS Code: открой оба файла, копипаст.

git add .github/workflows/deploy.yml
git commit -m "Add GitHub Actions deploy workflow (task 30)"
git push origin main

Шаг 7: проверка

Первый запуск триггерится автоматически на push из шага 6. Смотри вкладку Actions в репо: https://github.com/oswold1979/alatyr-taverna/actions

Ожидаемая длительность: ~2 минуты (SSH connect + git fetch + npm ci + build + rsync + reload).

Как понять что работает:

curl -I https://alatyr-taverna.ru
# HTTP/2 200
# content-type: text/html

Отладка если упало

1. Permission denied (publickey): - Приватный ключ в VPS_SSH_KEY не соответствует публичному в authorized_keys (проверь что скопировал весь блок BEGIN/END без лишних пробелов)

2. sudo: a password is required: - Sudoers из шага 2 не применился или команда в workflow отличается от разрешённой. Проверь sudo -n rsync ... от юзера oswold.

3. npm ci не находит node_modules dev-зависимостей: - alatyr-taverna использует vite build который требует devDependencies. npm ci их ставит по умолчанию — всё должно работать. Проверь версию npm (>=8).

4. Build успешен, но сайт не обновился: - rsync работал, но nginx кэширует. Проверь заголовки: curl -I https://alatyr-taverna.ru — если age: > 0 → cache. Проверь nginx конфиг:

sudo cat /etc/nginx/sites-enabled/alatyr-taverna | grep -A2 cache

5. dist/index.html не найден: - tsc -b (первый шаг npm run build) упал на TypeScript ошибках. Смотри логи Actions.

Что даёт этот workflow

  • Push в main → автодеплой за 2 минуты, без ручного SSH
  • Rollback: git revert HEAD && git push — workflow автоматически откатит
  • Manual trigger: ActionsDeploy alatyr-tavernaRun workflow
  • Дифференциальный rsync с --delete — старые chunks Vite не остаются
  • Проверка health (curl 200) с fail-fast если что-то не так
  • Nginx logs автоматически дампятся в Actions при failure

Отличие от старого (сломанного 25.07) workflow

Что было не так (см. alatyr-taverna.md): - Пытались билдить в Actions и через rsync лить готовый dist/ на VPS - rsync через SSH из GitHub требовал SSH_PRIVATE_KEY + прописать путь + sudoers → 4 точки отказа - Не было проверки что build реально создался - Не было fail-dump nginx logs

Что теперь: - Build на VPS (git pull, npm ci, npm run build) — консистентно с alatyr-service - Одна команда rsync внутри VPS (быстрая, локальная) - Sudoers ограничен ровно тремя командами (nginx -t, systemctl reload, rsync) - Fail-fast если dist/index.html не создался - Automatic dump логов на failure