Тема форума для уведомлений бэкапов задаётся только env-файлом на хосте, а в
образцах её не было вовсе. На проде она задана, но не та: 158 («алерты») в
/opt/gendesign/secrets/backup-notify.env и forgejo-backup.env на Beget и в
/etc/default/gendesign-backup на Poincare. По решению #3163 инфраструктура идёт
в 245 «Metrics». Значение на хостах этот коммит не меняет.
- ops/gendesign-backup*.default.example: строка #TELEGRAM_TOPIC_ID=245 с
причиной и ловушкой: тема обязана лежать в одном файле с токеном и чатом,
иначе notify() её не прочитает.
- ops/crontab-beget.cron сверен с живым crontab Beget: сторожа и бэкап волта
получают BACKUP_ENV_FILE=/opt/gendesign/secrets/backup-notify.env. Без него
переустановка crontab из репозитория глушила бы алерты бэкапов на Beget.
- ops/uptime-healthcheck.sh и его образец удалены: скрипт не запущен ни на
одном хосте (crontab, cron.d, таймеры), доступность сторожат uptime-мониторы
GlitchTip на Beget (gendsgn.ru, /health, meraocenka.ru — раз в 60 с).
Тест исполняет настоящий check-backup-staleness.sh с образцом, заполненным
по инструкции, и проверяет адрес в вызове curl: message_thread_id=245.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deliverable 1: ops/backup.sh and tradein-mvp/deploy/backup-tradein-db.sh now
write a sentinel file on every verified-good run. A new ops/check-backup-
staleness.sh (separate cron entry, hourly) alerts via the existing Telegram
channel (same TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID idiom as ops/uptime-
healthcheck.sh, transition-tracked so it doesn't spam) if a sentinel goes
stale. Shared logic (notify/sentinel/state) factored into ops/lib-backup.sh
so it isn't triplicated; the two existing scripts' own hardening (integrity
checks, retention, etc.) is untouched.
Deliverable 2: ops/backup-forgejo.sh — Forgejo (git.gendsgn.ru) has no backup
today. Dumps the shared-postgres `forgejo` DB + tars the bare-repo tree, both
off-box to s3://gendsgn-backups/forgejo/ under a SEPARATE, narrower S3 key
(root-of-bucket writer key stays out of this). The key doesn't exist yet —
the script refuses to run and exits non-zero, loudly, until the four
FORGEJO_S3_* vars are filled in (see the example env file and PR description
for the exact bucket policy JSON to create it with).
Refs #2203, #2989
- ops/backup.sh и tradein-mvp/deploy/backup-tradein-db.sh теперь дампят
globals (pg_dumpall --globals-only) отдельным файлом с той же ретенцией
и той же S3-выгрузкой — pg_dump по определению не включает роли/GRANT.
- Обе выгрузки проходят gzip -t + проверку трейлера дампа перед тем как
считаться успешными; при провале файл удаляется, ретенция не трогается,
выход ненулевой.
- Убран 2>/dev/null у pg_dump в обоих скриптах — ошибка дампа теперь
видна в логе, а не глотается молча.
- tradein-backup.sh получил S3-выгрузку (по образцу ops/backup.sh, те же
4 переменные, тот же способ через aws-cli контейнер) и env-переопределяемый
порог минимального размера дампа; источник переменных —
/etc/default/tradein-backup с фолбэком на /etc/default/gendesign-backup.
- Новый ops/restore-drill.sh — учебное восстановление в одноразовый
postgis-контейнер без прод-томов, никогда не трогает боевую БД (в отличие
от ops/restore.sh, который восстанавливает В БОЕВУЮ базу).