gendesign/.forgejo/workflows
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
..
ci-tradein.yml fix(db/ci): чистый старт БД больше не падает на 077 и не может уехать на пустой схеме 2026-08-20 23:31:46 +03:00
ci.yml fix(ci): прод-деплои в одну группу concurrency — прун одного убивал pull другого (#2950) (#2952) 2026-08-20 07:47:48 +00:00
deploy-infra.yml feat(ops): у волта Obsidian появился автоматический бэкап 2026-08-25 08:37:02 +03:00
deploy-obsidian.yml fix(ci): стек CouchDB после переезда остаётся на своём хосте (#3087) 2026-08-24 17:58:56 +00:00
deploy-tradein.yml feat(ci): деплой проверяет, к тому ли хосту подключился (#3079) 2026-08-24 16:36:50 +00:00
deploy.yml chore(ci): деплой не убивает worker посреди скрап-прогона (#3084) 2026-08-24 17:25:23 +00:00
perimeter-smoke.yml ci: смоук периметра МЕРЫ запускается сразу после деплоя (#2917) (#2922) 2026-08-19 08:13:49 +00:00
stale-claims.yml fix(stale-claims): avoid SIGPIPE 141 — pass file path не pipe 2026-05-28 01:05:56 +03:00