gendesign/ops
bot-backend 0111b32cb2
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
feat(ops): у волта Obsidian появился автоматический бэкап
Site Finder закрывает backup.sh, МЕРУ — backup-tradein-db.sh, Forgejo —
backup-forgejo.sh. CouchDB не закрывал никто: автоматического бэкапа волта не
существовало вообще, единственной копией был ручной месячный прогон на машине
владельца. При этом в волте вся накопленная база знаний проекта — решения,
разборы инцидентов, ограничения, — и восстановить её из кода нельзя.

Контейнер на время снимка останавливается. Файлы CouchDB пишутся append-only,
но копия работающего узла может застать запись между обновлением данных и
обновлением заголовка базы, а .shards/ и _dbs.couch — рассогласованными между
собой; документация прямо требует снимать file-level копию с остановленного
узла. Данных около 85 МБ, простой измерен и составляет примерно минуту, окно
ночное, а LiveSync к обрывам связи устойчив по своей природе.

Оставить волт лежать — отказ хуже отсутствия бэкапа, поэтому старт висит на
trap EXIT и отрабатывает при любом выходе, включая ошибку tar и нехватку
места. После подъёма проверяется, что /_up отвечает, иначе notify().

S3 обязателен, как в backup-forgejo.sh и в backup.sh после #3085: без ключей
скрипт падает ДО остановки контейнера. Ронять волт ради копии, которой некуда
уехать, незачем.

Отдельный ключ для волта не требуется. Если COUCHDB_S3_* не заданы, берутся
S3_* из конфига основного бэкапа — того же ключа, которым уже выгружается
Site Finder, но под своим префиксом couchdb/. Требовать узкий ключ как условие
запуска значило бы оставить волт без бэкапа до того дня, когда до ключа дойдут
руки; завести его никто не мешает, файл-образец для этого есть.

Фолбэк читается в ПОДОБОЛОЧКЕ, наружу выносятся ровно четыре значения. Прямой
source был бы тихой диверсией: конфиг основного бэкапа задаёт свои
LOCAL_BACKUP_DIR, KEEP и SENTINEL_FILE, они затёрли бы вычисленные для волта.
Архивы легли бы в чужой каталог, а write_sentinel обновил бы сентинел
ОСНОВНОГО бэкапа — его сторож свежести зеленел бы по чужому прогону, и
пропущенный дамп базы перестал бы замечаться.

Владелец архивов выравнивается внутри контейнера: читать том надо от root,
поэтому наружу файлы выходили root:root, в отличие от соседних серий. Ротацию
это не ломало, но ставило каталог в зависимость от отсутствия sticky-бита.

ops/*.cron добавлен в paths deploy-infra.yml: эта строка была только в
deploy.yml, и после разъезда хостов правка crontab-beget.cron доезжала бы
лишь до продового хоста — то есть не туда, где живёт волт.

Проверено на боевом Beget, дважды подряд:
- без S3-настроек — код возврата 1, контейнер не тронут (Up 12 hours);
- полный прогон — контейнер остановлен, снят снимок 53 219 001 байт (15
  файлов) и конфиг 788 байт (3 файла), контейнер поднят и healthy, оба архива
  выгружены, сентинел записан, весь прогон 103 с;
- изоляция подоболочки прогнана на подставном конфиге: S3-значения
  подхватываются, LOCAL_BACKUP_DIR / SENTINEL_FILE / KEEP не затираются;
- объекты в бакете подтверждены НЕЗАВИСИМЫМ читающим ключом:
  couchdb/couchdb-data_*.tar.gz 50.8 MiB и couchdb/couchdb-config_*.tar.gz.

Refs #3057, #3085
2026-08-25 08:37:02 +03:00
..
db-bootstrap feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
glitchtip-auth-forwarder fix(tradein/observability): stop basic_auth 401 and RetryError GlitchTip noise 2026-08-15 18:08:04 +03:00
backup-couchdb.sh feat(ops): у волта Obsidian появился автоматический бэкап 2026-08-25 08:37:02 +03:00
backup-forgejo.sh feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
backup.sh fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
check-backup-staleness.sh fix(ops): restore +x on new ops/*.sh (exec bit lost in prior commit, Windows core.filemode=false) 2026-08-21 15:38:31 +03:00
crontab-beget.cron feat(ops): у волта Obsidian появился автоматический бэкап 2026-08-25 08:37:02 +03:00
crontab-poincare.cron fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
docker-prune.sh chore(ops): снятие зависших job-контейнеров раннера + лимит journald + мёртвый Caddy-блок 2026-08-15 22:27:48 +03:00
gendesign-backup-couchdb.default.example feat(ops): у волта Obsidian появился автоматический бэкап 2026-08-25 08:37:02 +03:00
gendesign-backup-forgejo.default.example feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
gendesign-backup.default.example fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
gendesign-uptime.default.example ci(infra): coverage-gate (#68) + OpenAPI codegen-assert (#69) + uptime monitoring (#75) 2026-06-13 23:28:06 +05:00
journald-gendesign.conf.example chore(ops): снятие зависших job-контейнеров раннера + лимит journald + мёртвый Caddy-блок 2026-08-15 22:27:48 +03:00
lib-backup.sh fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
restore-drill.sh fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
restore.sh fix(ops): восстановление не падает в хвосте из-за незаведённых ролей (#3089) 2026-08-25 05:18:53 +00:00
selectel-audit.sh feat(ci): деплой проверяет, к тому ли хосту подключился (#3079) 2026-08-24 16:36:50 +00:00
selectel-bootstrap.sh fix(ops): закрепить рабочий адрес api.telegram.org на новом хосте 2026-08-23 23:32:35 +03:00
selectel-ci-access.sh feat(ci): деплой проверяет, к тому ли хосту подключился (#3079) 2026-08-24 16:36:50 +00:00
split-infra-postgres.sh feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
uptime-healthcheck.sh ci(infra): coverage-gate (#68) + OpenAPI codegen-assert (#69) + uptime monitoring (#75) 2026-06-13 23:28:06 +05:00