feat(books-backup): bookva-es snapshot via Portainer path.repo

bookva-es (отдельный ES 7.10, Portainer stack 37) не снапшотился — path.repo
не сконфигурирован. Пересоздан через Portainer API (PUT /api/stacks/37) с
path.repo=/snapshots + bind /usr/docker/bookva-es/snapshots (uid 1000:0);
внешний том bookva-es-data сохранён (epz/products целы). Repo kreknin
зарегистрирован.

Добавлен Step 2b (bookva-es snapshot + prune) в run.sh.

Gotcha пойман на проверке приёмника ДО коммита: оба ES-каталога называются
`snapshots` → как отдельные rsync-источники сливаются в один dest/snapshots/
и портят оба репо (видно по двойному index-N). Fix: источник bookva-es =
родительский /usr/docker/bookva-es (basename bookva-es → dest/bookva-es/snapshots/).

Verified green: BOOKS-VDS backup OK 10m28s, на kreknin раздельно
snapshots/ (slovo, index-41, 795M) + bookva-es/snapshots/ (index-4, 801M),
по одному index-N в каждом → оба независимо рестораблельны.

Закрывает .tasks/bookva-es-snapshot-repo.md (🟢). bookva tenant полностью
покрыт (db/mongo/minio/es).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-12 11:56:19 +03:00
parent aeb82a6a70
commit e001b8e331
5 changed files with 38 additions and 8 deletions

View File

@@ -160,6 +160,34 @@ if [ $PRUNE_COUNT -gt 0 ]; then
done
fi
# === Step 2b: bookva-es snapshot (separate ES, own /snapshots repo, added 2026-06-12) ===
echo "--- bookva-es snapshot $ES_SNAP in repo $ES_SNAPSHOT_REPO ---"
BSNAP_RESULT=$(docker exec bookva-es curl -sS -X PUT \
"http://localhost:9200/_snapshot/$ES_SNAPSHOT_REPO/$ES_SNAP?wait_for_completion=true" \
-H 'Content-Type: application/json')
echo "bookva-es snapshot result: $BSNAP_RESULT"
if ! echo "$BSNAP_RESULT" | grep -q '"state":"SUCCESS"'; then
echo "bookva-es snapshot did NOT report SUCCESS state — failing"
exit 3
fi
echo "--- prune bookva-es snapshots older than $RETENTION_DAYS ---"
BALL_SNAPS=$(docker exec bookva-es curl -sS "http://localhost:9200/_snapshot/$ES_SNAPSHOT_REPO/_all" \
| grep -oE '"snapshot":"daily-[0-9-]+"' \
| sed -E 's/.*"(daily-[0-9-]+)".*/\1/' \
| sort)
BSNAP_COUNT=$(echo "$BALL_SNAPS" | wc -l)
BPRUNE_COUNT=$((BSNAP_COUNT - RETENTION_DAYS))
if [ $BPRUNE_COUNT -gt 0 ]; then
echo "$BALL_SNAPS" | head -n "$BPRUNE_COUNT" | while read -r snap; do
[ -z "$snap" ] && continue
echo "deleting bookva-es snapshot: $snap"
docker exec bookva-es curl -sS -X DELETE \
"http://localhost:9200/_snapshot/$ES_SNAPSHOT_REPO/$snap" || true
echo
done
fi
# === Step 3: rsync to kreknin ===
echo "--- rsync to $DEST_USER@$DEST_HOST:$DEST_PATH ---"
ssh $SSH_OPTS "$DEST_USER@$DEST_HOST" "mkdir -p '$DEST_PATH'"
@@ -173,6 +201,7 @@ rsync -aHh --info=stats2 --delete $LINK_DEST_ARG \
-e "ssh $SSH_OPTS" \
/opt/books \
/usr/docker/elasticsearch/snapshots \
/usr/docker/bookva-es \
/usr/docker/minio/data \
/var/lib/docker/volumes/bookva-minio-data \
/usr/docker/traefik/letsencrypt \
@@ -220,7 +249,7 @@ Components:
- /root/.ssh
- DB dumps: books-db (mariadb), mongo (shared), books-job-scheduler-mongo, bookva-db (mariadb), bookva-mongo
- bookva-minio: raw volume (bookva-minio-data)
- ES snapshot (slovo): $ES_SNAP [bookva-es: derivative index == slovo, snapshot pending Portainer path.repo]
- ES snapshots: $ES_SNAP (slovo elasticsearch + bookva-es, separate repos)
Log: $LOG"
email_send "[$HOST_LABEL] backup OK $TODAY" "$EMAIL_BODY"