Files
admin/vds-backup-rsync-kreknin.md
vitya f9bdb97be3 docs(.wiki,.tasks): vds-kzntsv-bootstrap done — 3 phases shipped
VDS Rusonyx 160 NVMe (89.253.255.94 / vds.kzntsv.site) активирован
2026-05-20. 3 фазы за ~6 часов:

- Phase 1: harden + docker 29.5.1 + traefik v2.11 + portainer 2.21.5
- Phase 2: shared DB park (postgres 16 / mariadb 11.4 / mongo 7 /
  redis 7) via traefik raw TCP forward + self-signed TLS
- Phase 3: миграция gitea (132 repos), verdaccio (2063 pkgs), registry
  fresh install (user accepted loss old images) + Joxit GUI

Ingest 1 source + 1 entity (vds-kzntsv) + 6 concepts (traefik-tcp-
passthrough-vs-starttls / portainer-2.21-admin-password-regression /
db-tls-self-signed-via-traefik-raw-tcp / rusonyx-vps-onboarding-quirks
/ registry-gc-mount-and-modify-flag / compose-bcrypt-escape-trap).

3 follow-up  tasks: vds-gc-cron, vds-backup-rsync-kreknin, vds-ntfy-push.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:39:31 +03:00

4.7 KiB
Raw Blame History

vds-backup-rsync-kreknin

Goal

Ежедневный rsync-бэкап важных директорий с VDS (89.253.255.94 / vds.kzntsv.site) → kreknin-synology (195.19.90.188 / kreknin.site) в 05:00 MSK. После каждого прохода — email-нотификация на vitya.kuznetsov@gmail.com со статусом (success/fail + transferred bytes + duration).

Open questions

  • Что бэкапить:
    • /opt/stacks/ — все compose-стеки и их data (включая gitea/data/, verdaccio/storage/, registry/docker/, databases/*/data/, traefik/letsencrypt/, portainer/data/). Большой объём.
    • /etc/ — system config (sshd_config, ufw, fail2ban, /etc/hosts, /etc/docker/, /etc/letsencrypt если есть).
    • ~/.ssh/ для vitya — authorized_keys.
    • DBs: rsync raw datadir постгреса/мариа/монги — НЕ безопасно (running container держит locks). Нужен pg_dump / mysqldump / mongodump ПЕРЕД rsync — сложнее.
  • Куда на kreknin: /volume1/NetBackup/vds-kzntsv/ (или новая шара). Retention — daily 7 days, weekly 4, monthly 6 — через --link-dest hardlink-cascade или borg/restic.
  • Заходить на kreknin через SSH: vitya@195.19.90.188, ключ id_ed25519_kreknin. Но ключ сейчас лежит на VDS в /home/vitya/.ssh/id_ed25519_kreknin (скопировал во время Phase 3 миграции) — продолжать использовать?
  • Tool: raw rsync с --link-dest (built-in, простой); или restic/borg (encrypted, dedup, push). Encrypted backups важны если канал между VDS↔kreknin не доверять.
  • Email механизм: установить msmtp + mailx на VDS, конфиг → SMTP через smtp.yandex.ru:465 (creds — в ~/projects/.common/secrets/noreply-snolla-smtp.env на Windows-side; на VDS залить аналог через scp). Или использовать curl --mail-from ... smtp://.

Implementation sketch

/etc/cron.d/vds-backup:

# 05:00 MSK ежедневно
0 5 * * * vitya /opt/stacks/backup/scripts/run.sh

/opt/stacks/backup/scripts/run.sh:

#!/bin/bash
set -e
SOURCE_DIRS=(/opt/stacks/gitea/data /opt/stacks/verdaccio/storage /opt/stacks/verdaccio/config /opt/stacks/registry/docker /opt/stacks/registry/auth /opt/stacks/traefik /opt/stacks/portainer/data /etc/ssh /etc/ufw /etc/hosts /etc/docker /etc/letsencrypt)
DEST_BASE=/volume1/NetBackup/vds-kzntsv
TODAY=$(date +%Y-%m-%d)
LATEST=$DEST_BASE/latest

START_TIME=$(date +%s)
LOG=/tmp/backup-$TODAY.log

# DB dumps первым шагом — pg/maria/mongo в /tmp/db-dumps/$TODAY/, потом включаются в rsync
mkdir -p /tmp/db-dumps/$TODAY
docker exec postgres pg_dumpall -U postgres > /tmp/db-dumps/$TODAY/postgres.sql
docker exec mariadb mariadb-dump --all-databases -u root -p"$MARIA_PASS" > /tmp/db-dumps/$TODAY/mariadb.sql
docker exec mongo mongodump --out=/tmp/mongo --uri="mongodb://root:$MONGO_PASS@localhost:27017?tls=true&tlsAllowInvalidCertificates=true"
docker exec redis redis-cli --tls --insecure -a "$REDIS_PASS" --rdb /data/dump.rdb

# rsync с --link-dest для hardlink-incremental
rsync -azh --link-dest=$LATEST "${SOURCE_DIRS[@]}" /tmp/db-dumps/$TODAY \
  -e "ssh -i ~/.ssh/id_ed25519_kreknin" \
  vitya@195.19.90.188:$DEST_BASE/$TODAY/

ssh -i ~/.ssh/id_ed25519_kreknin vitya@195.19.90.188 \
  "rm -f $LATEST && ln -sf $DEST_BASE/$TODAY $LATEST"

END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
SIZE=$(du -sh $DEST_BASE/$TODAY 2>/dev/null | cut -f1)

# Email via msmtp
echo "Subject: VDS backup $TODAY — SUCCESS

Size: $SIZE, duration: ${DURATION}s
Source: vds.kzntsv.site
Dest: kreknin.site:$DEST_BASE/$TODAY/
" | msmtp vitya.kuznetsov@gmail.com

(скетч; добавить retention prune — find $DEST_BASE -maxdepth 1 -type d -name "20*" | sort | head -n -7 | xargs rm -rf, error trap, etc.)

Decisions log

  • Пусто — задача только заведена.

Notes

  • Триггер: после [[vds-kzntsv-bootstrap]] Phase 3 + verdaccio/registry стабильны.
  • SMTP creds: C:\Users\vitya\projects\.common\secrets\noreply-snolla-smtp.env (Windows-side, не в git'е). Сериализовать в /etc/msmtprc на VDS аккуратно (chmod 600).
  • Retention vs disk: kreknin имеет ~5.6 TB free; daily 30 + weekly 6 + monthly 12 = ~50 snapshots, при ~10G inc + ~50G full = ~500G total. OK headroom.
  • Не бэкапить acme.json в plain текст — содержит LE private keys. Encrypt через restic OR пропустить.