All checks were successful
Deploy Infra Host / sync-infra-host (push) Successful in 2s
Deploy / changes (push) Successful in 7s
Deploy / deploy-caddy (push) Has been skipped
Deploy / perimeter-smoke (push) Successful in 10s
Deploy / build-backend (push) Successful in 50s
Deploy / build-frontend (push) Successful in 51s
Deploy / build-worker (push) Successful in 53s
Deploy / deploy (push) Successful in 1m43s
Deploy / deploy-status (push) Successful in 1s
131 lines
8.9 KiB
YAML
131 lines
8.9 KiB
YAML
name: Deploy Infra Host
|
||
|
||
# Синхронизация /opt/gendesign на ХОСТЕ, КОТОРЫЙ ОСТАЁТСЯ (#3059, #3057).
|
||
#
|
||
# ЗАЧЕМ. Сегодня Beget — и прод, и инфраструктура одновременно, поэтому его
|
||
# рабочее дерево обновляет обычный `deploy.yml` (шаг `git reset --hard
|
||
# origin/main` по SSH на `secrets.DEPLOY_HOST`). После переезда 30.08
|
||
# `DEPLOY_HOST` станет указывать на Selectel — и /opt/gendesign на Beget
|
||
# перестанет обновляться СОВСЕМ. Молча.
|
||
#
|
||
# А из этого каталога на Beget продолжат работать:
|
||
# - cron-скрипты бэкапов: ops/backup.sh, ops/backup-forgejo.sh,
|
||
# ops/check-backup-staleness.sh, ops/lib-backup.sh, ops/docker-prune.sh
|
||
# - docker-compose.prod.yml для Forgejo / GlitchTip / CouchDB
|
||
# - Caddyfile + caddy/sites/infra.caddy — единственный публичный вход для
|
||
# git.gendsgn.ru, errors.gendsgn.ru, obsidian.gendsgn.ru (#3062)
|
||
#
|
||
# То есть любая будущая правка этих файлов легла бы в main и никогда не доехала
|
||
# до машины, которая их исполняет. Это ровно класс #2887 («скрипт запускается по
|
||
# cron из /opt/gendesign, куда попадает только через git reset --hard шага
|
||
# деплоя»), но не на уровне одного файла, а на уровне целого хоста.
|
||
#
|
||
# ПОЧЕМУ ОТДЕЛЬНЫЙ WORKFLOW, А НЕ JOB В deploy.yml. Разные адресаты и разные
|
||
# вердикты: «выкатили приложение на Selectel» и «синхронизировали инфраструктуру
|
||
# на Beget» — два независимых факта, и падение второго не должно читаться как
|
||
# неудавшийся деплой продукта. Плюс триггеры разные: инфра-хосту не нужны
|
||
# пересборки backend/frontend.
|
||
#
|
||
# ИНЕРТЕН, ПОКА НЕ ЗАДАН INFRA_DEPLOY_HOST. Сейчас, до переезда, Beget и есть
|
||
# DEPLOY_HOST — второй проход по тому же хосту был бы лишним и мог бы состязаться
|
||
# с основным деплоем за докер-демон (#2950). Поэтому job не делает ничего, пока
|
||
# секрет пуст: включается ОДНОЙ настройкой в момент, когда хосты разъедутся.
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
paths:
|
||
# Ровно то, что исполняется НА ОСТАЮЩЕМСЯ хосте. Намеренно НЕ включены
|
||
# backend/** и frontend/** — их образы туда не едут.
|
||
- "ops/*.sh"
|
||
- "Caddyfile"
|
||
- "caddy/**"
|
||
- "docker-compose.prod.yml"
|
||
- "docker-compose.obsidian.yml"
|
||
- ".forgejo/workflows/deploy-infra.yml"
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
sync-infra-host:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Проверить, разъехались ли хосты
|
||
id: gate
|
||
env:
|
||
INFRA_HOST: ${{ secrets.INFRA_DEPLOY_HOST }}
|
||
run: |
|
||
set -euo pipefail
|
||
if [ -z "${INFRA_HOST:-}" ]; then
|
||
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||
echo "INFRA_DEPLOY_HOST не задан — хосты ещё не разъехались."
|
||
echo "Инфраструктуру обновляет обычный deploy.yml. Ничего не делаю."
|
||
else
|
||
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
||
echo "INFRA_DEPLOY_HOST задан — синхронизирую остающийся хост."
|
||
fi
|
||
|
||
- name: Синхронизировать /opt/gendesign на остающемся хосте
|
||
if: steps.gate.outputs.enabled == 'true'
|
||
uses: appleboy/ssh-action@v1.0.3
|
||
with:
|
||
host: ${{ secrets.INFRA_DEPLOY_HOST }}
|
||
username: ${{ secrets.INFRA_DEPLOY_USER || secrets.DEPLOY_USER }}
|
||
key: ${{ secrets.INFRA_DEPLOY_SSH_KEY || secrets.DEPLOY_SSH_KEY }}
|
||
port: ${{ secrets.INFRA_DEPLOY_PORT || secrets.DEPLOY_PORT }}
|
||
script: |
|
||
set -euo pipefail
|
||
cd /opt/gendesign
|
||
git fetch origin main
|
||
git reset --hard origin/main
|
||
|
||
# Тот же chmod, что и в deploy.yml: cron зовёт скрипты через `bash`,
|
||
# но restore-drill и ручные запуски рассчитывают на +x.
|
||
chmod +x ops/*.sh 2>/dev/null || true
|
||
|
||
# Caddy здесь несёт ТОЛЬКО остающиеся домены (CADDY_SITES=infra).
|
||
# reload, а не recreate: конфиг примонтирован read-only, контейнер
|
||
# читает тот же файл, который только что обновил git. Если конфиг
|
||
# невалиден — reload откажет ГРОМКО, а старый останется работать,
|
||
# то есть падение здесь не роняет git/errors/obsidian.
|
||
if docker ps --format '{{.Names}}' | grep -q '^gendesign-caddy-1$'; then
|
||
docker compose -p gendesign -f docker-compose.prod.yml exec -T caddy \
|
||
caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
|
||
echo "✓ конфиг прокси перезагружен"
|
||
else
|
||
echo "⚠ контейнер caddy не найден — пропускаю reload"
|
||
fi
|
||
|
||
# infra-postgres (#3061): применить изменения конфигурации сервиса.
|
||
# После разъезда хостов этот workflow — ЕДИНСТВЕННОЕ, что доставляет
|
||
# docker-compose.prod.yml на Beget, а лёгкий кластер БД описан именно
|
||
# там. Без этой строки любой будущий бамп postgres:16-alpine, правка
|
||
# mem_limit или healthcheck'а легли бы в main, workflow отрапортовал
|
||
# бы «дерево синхронизировано», а контейнер продолжил бы жить со
|
||
# старой конфигурацией по `restart: unless-stopped` — молча, ровно
|
||
# класс #2887, ради которого этот workflow и написан.
|
||
#
|
||
# `up -d` с ЯВНЫМ именем сервиса, а не общий: трогается только
|
||
# infra-postgres, до Forgejo / GlitchTip / CouchDB дела нет. Явное
|
||
# имя заодно активирует профиль `infra` само по себе, без оглядки на
|
||
# COMPOSE_PROFILES. Если конфигурация не менялась — compose ничего не
|
||
# пересоздаёт, шаг стоит доли секунды.
|
||
#
|
||
# СОЗДАВАТЬ кластер отсюда мы НЕ хотим — отсюда проверка на
|
||
# существующий контейнер. Первый старт — осознанный ручной шаг окна
|
||
# переезда (шаг 2 в docker-compose.prod.yml), и делается он с уже
|
||
# заполненными INFRA_PG_PASSWORD / FORGEJO_DB_PASS. Стартуй мы вслепую
|
||
# — пустой пароль дал бы отравленный том, который потом не
|
||
# переинициализировать.
|
||
if docker ps -a --format '{{.Names}}' | grep -qx 'gendesign-infra-postgres'; then
|
||
docker compose -p gendesign -f docker-compose.prod.yml up -d infra-postgres
|
||
echo "✓ infra-postgres приведён к конфигурации из main"
|
||
else
|
||
echo "⚠ контейнер gendesign-infra-postgres не найден — кластер ещё не поднят вручную, пропускаю"
|
||
fi
|
||
|
||
# НАМЕРЕННО НЕ ДЕЛАЕТСЯ:
|
||
# - docker image prune: конкурирует с деплоем продукта за leases
|
||
# докер-демона (#2950). Прун на этом хосте остаётся за
|
||
# еженедельным ops/docker-prune.sh.
|
||
# - перезапуск Forgejo / GlitchTip / CouchDB: правка ops-скрипта
|
||
# не повод ронять git. Их обновление — осознанное действие.
|
||
echo "✓ рабочее дерево синхронизировано: $(git rev-parse --short HEAD)"
|