feat(ops): у волта Obsidian появился автоматический бэкап #3090
Merged
lekss361
merged 1 commit from 2026-08-25 05:44:17 +00:00
feat/3057-couchdb-backup into main
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0111b32cb2 |
feat(ops): у волта Obsidian появился автоматический бэкап
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
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 |