gendesign/ops/gendesign-backup-forgejo.default.example
bot-backend 7218c2094c
All checks were successful
CI Trade-In / changes (pull_request) Successful in 24s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 29s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 3m15s
CI / backend-tests (pull_request) Successful in 7m37s
Бэкапы: образцы env ведут алерты в тему «Metrics», мёртвый uptime-сторож удалён (#3164)
Тема форума для уведомлений бэкапов задаётся только 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>
2026-09-17 12:49:33 +05:00

91 lines
7.1 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Environment file for ops/backup-forgejo.sh (Forgejo code + DB backup, #2203).
#
# Install on the prod VM as a ROOT-OWNED, chmod-600 file that is NOT in git:
# sudo cp /opt/gendesign/ops/gendesign-backup-forgejo.default.example /etc/default/gendesign-backup-forgejo
# sudo chmod 600 /etc/default/gendesign-backup-forgejo
# sudo $EDITOR /etc/default/gendesign-backup-forgejo # fill in real S3 credentials
#
# DELIBERATELY a separate file from /etc/default/gendesign-backup (used by
# ops/backup.sh and tradein-mvp/deploy/backup-tradein-db.sh) — this backup
# uses a SEPARATE, narrower-scoped S3 service user that can ONLY PutObject
# under s3://gendsgn-backups/forgejo/*, nothing else. The prod-host writer
# key used by the other two backups (`gendsgn-backup-writer`) has root-of-
# bucket access; that key must NOT be reused here, and this key must NOT be
# put in /etc/default/gendesign-backup.
#
# THE KEY DOES NOT EXIST YET (as of #2203). Until a human creates the
# `gendsgn-backup-forgejo-writer` service user + bucket policy in the
# Selectel panel (see the #2203 PR description for the exact policy JSON —
# PutObject-only on arn:aws:s3:::gendsgn-backups/forgejo/*, explicit Deny on
# GetObject/ListBucket/Delete*) and fills in the four FORGEJO_S3_* vars
# below, ops/backup-forgejo.sh refuses to run and exits non-zero loudly. That
# is expected, not a bug.
#
# --- S3 off-site upload (Selectel S3-compatible). All four required. ---
#FORGEJO_S3_ENDPOINT=https://s3.ru-1.storage.selcloud.ru
#FORGEJO_S3_BUCKET=gendsgn-backups
#FORGEJO_S3_ACCESS_KEY=REPLACE_WITH_REAL_ACCESS_KEY_ONCE_CREATED
#FORGEJO_S3_SECRET_KEY=REPLACE_WITH_REAL_SECRET_KEY_ONCE_CREATED
# --- оповещения (Telegram) ---
# backup-forgejo.sh читает этот файл сам, поэтому канал задаётся здесь: без
# токена и чата notify() ищет их в /etc/default/gendesign-backup.
#TELEGRAM_BOT_TOKEN=123456789:AA-REPLACE_WITH_REAL_BOT_TOKEN
#TELEGRAM_CHAT_ID=123456789
# Тема форума (#3164). Бэкапы — инфраструктура, по решению #3163 они идут в
# «Metrics» (245); «алерты» (158) — только для клиентских инцидентов. Без
# переменной сообщение уходит в общую тему. Держать В ТОМ ЖЕ файле, что токен и
# чат: notify() читает env-файл, только если их нет в окружении.
#TELEGRAM_TOPIC_ID=245
# --- optional overrides (defaults are sensible; uncomment only to change) ---
#FORGEJO_S3_PREFIX=forgejo/ # key prefix inside the bucket; must match
# the policy's Resource path exactly
#KEEP=7 # how many recent local copies to retain
# (DB dumps and repo bundles are separate series)
#MIN_DB_DUMP_BYTES=2048 # sanity floor for the DB dump (small DB —
# config/issues/PRs/users, no git blobs)
#MIN_REPOS_BUNDLE_BYTES=10240 # sanity floor for the repo tar.gz
#LOCAL_BACKUP_DIR=/opt/gendesign/backups/forgejo
#FORGEJO_DIR=/home/gendesign/forgejo # Forgejo compose dir on the VM (NOT
# part of the gendesign git checkout)
#FORGEJO_REPOS_DIR=/home/gendesign/forgejo/data/forgejo/git/repositories
# --- контейнер с БД Forgejo (#3061) ---
# ЗАДАВАТЬ НЕ НУЖНО почти никогда: ops/backup-forgejo.sh находит контейнер сам.
# Он перебирает PG_CONTAINER_CANDIDATES, оставляет запущенные и берёт тот, в
# чьей базе `forgejo` реально ЕСТЬ ТАБЛИЦЫ.
#
# ПОЧЕМУ НЕ КОНСТАНТА. Раньше имя было зашито (gendesign-postgres-1 — общий
# кластер основного приложения). Переезд продукта на Selectel переносит базу
# forgejo оттуда в лёгкий инфраструктурный кластер (gendesign-infra-postgres,
# сервис infra-postgres в docker-compose.prod.yml), а старый контейнер после
# переноса какое-то время ещё жив и держит свою — с этого момента протухающую —
# копию базы. Зашитое имя означало бы, что бэкап продолжает исправно дампить
# именно её: дамп непустой, маркер завершения на месте, размер выше порога — и
# ни одной новой строки с момента cutover. Порогов на СВЕЖЕСТЬ здесь нет, так
# что выяснилось бы это только при восстановлении.
#
# КОГДА ЗАДАВАТЬ ЯВНО — ровно один случай: окно переезда, когда непустая база
# forgejo есть СРАЗУ В ДВУХ запущенных контейнерах. Автоопределение тогда не
# гадает, а останавливается с ошибкой (выбрать наугад = 50% шанс забэкапить
# труп) и ждёт прямого указания, какой контейнер боевой. Момент, с которого это
# нужно, наступает НЕ на cutover'е, а РАНЬШЕ — с первой же заливки дампа в новый
# кластер (шаг 3a в комментарии к сервису infra-postgres,
# docker-compose.prod.yml): с этой секунды кандидатов двое, и ночной бэкап
# git-хоста иначе просто не снимется. Поэтому значение здесь живёт двумя фазами:
# до cutover'а — боевой ещё старый кластер:
#PG_CONTAINER=gendesign-postgres-1
# после — новый:
#PG_CONTAINER=gendesign-infra-postgres
# Строку УБРАТЬ, как только старый контейнер погашен: дальше автоопределение
# снова однозначно и переживёт любое следующее переименование само.
#
# Явное значение берётся КАК ЕСТЬ, без проверок — это ручной override, и тот,
# кто его выставил, знает про свою инсталляцию больше. Пустое значение
# (PG_CONTAINER=) равносильно незаданному: включается автоопределение.
# Где искать, когда PG_CONTAINER пуст. Имена через пробел; КАВЫЧКИ ОБЯЗАТЕЛЬНЫ —
# файл читается через `source`, и без них второе имя bash попытается выполнить
# как команду. Трогать только если контейнеры называются иначе, чем здесь.
#PG_CONTAINER_CANDIDATES="gendesign-postgres-1 gendesign-infra-postgres"