Borg Backup Infrastructure Report

s12 CyberPanel — WebFactor Production Backup System

24 февруари 2026

01 — Текущо състояние

Локален Borg

OK
Работи на всеки 2 часа

Remote Borg

FAIL
Всички remote бекъпи счупени

Диск s12

95%
108 GB свободни от 2 TB
📦

Borg Repo (s12)

Път/var/backups/borg-home
КриптиранеНяма
Архиви52
Оригинален размер13.46 TB (кумулативно)
Компресиран10.57 TB
Дедуплициран (реален)291.14 GB
Компресияzstd,8
/home/ размер266 GB
💻

s1-backups (дестинация)

ХостIncus контейнер на s1
Файлова системаZFS mainpool/backups
Общо40 TB
Заето203 GB (0.5%)
Свободно~40 TB
Borg инсталиранНе
Borg repoНе съществува
Наличен път/backups/cyberpanel/

02 — Критични проблеми

🔴

Няма работещ off-site бекъп

Всички remote borg бекъпи са счупени. backuprepo (Tailscale) — tmux retries fail. borgrepo1 — DNS не се resolve-ва. Логовете показват 6 последователни провала с rc=1. Единственият бекъп е локален — на същия диск.

🟠

Дискът на s12 е 95% пълен

Само 108 GB свободни от 2 TB. Borg repo-то заема 291 GB (14.5% от диска). С намаляване на retention от 52 седмици на 7 дни, очакваме спестяване на ~200 GB.

🟠

Borg не е инсталиран на s1-backups

Бекъп контейнерът на s1 има 40 TB свободни, но няма borg. Директорията /backups/cyberpanel/ съществува, но е празна. Трябва да се инсталира borg и да се създаде repo.

03 — Скриптове и инструменти

Всички скриптове са в cyberpanel LXD контейнера на s12.

СкриптПътСтатусОписание
borg-home-local.sh /root/scripts/backup/ Active Локален Borg create + prune + compact на /home
wp-export-all-db.sh /root/scripts/backup/ Active WP DB export за всички сайтове → wp-content/db-*.sql
backup-manager.sh /root/scripts/backup/ Active Интерактивно меню: backup / list / restore (+WP DB import)
borg-oneliner.sh /root/scripts/backup/ Disabled Remote borg към backuprepo (Tailscale), JSON summary
backup-home-borg.sh /root/ Failing Remote borg към backuprepo с tmux + retries
borg-repo-to-s1.sh /root/scripts/backup/ Unused rsync на borg repo към s1.webfactor.com
full-backup-to-s1.sh /root/scripts/backup/ One-time Пълен rsync бекъп (MySQL, /home, LiteSpeed, CyberPanel, Docker...)
backup-home.sh /root/ Broken Remote borg към borgrepo1 (DNS fail)

Текущ Cron (в cyberpanel контейнера)

# Активни задачи (всеки 2 часа) 0 */2 * * * /root/scripts/backup/wp-export-all-db.sh >> /var/log/wp-export-cron.log 2>&1 10 */2 * * * /root/scripts/backup/borg-home-local.sh >> /var/log/borg-home.log 2>&1 # Деактивирани (коментирани) #0 */4 * * * /root/scripts/wp-export-all-2.sh #15 */4 * * * /root/scripts/backup/borg-oneliner.sh

Retention Policy (текуща)

--keep-within=2d # всички архиви от последните 48 часа --keep-daily=7 # 1 на ден за 7 дни --keep-weekly=52 # 1 на седмица за 1 година ← яде 200 GB на s12

04 — Архиви (52 бр.)

Локален repo: /var/backups/borg-home — от 17 септември 2025 до 24 февруари 2026

#АрхивДатаТип
1cyberpanel-home-2025-09-17_06-11-5117.09.2025weekly
2cyberpanel-home-2025-09-21_22-10-0121.09.2025weekly
3cyberpanel-home-2025-09-28_22-10-0128.09.2025weekly
4cyberpanel-home-2025-10-05_22-10-0105.10.2025weekly
5cyberpanel-home-2025-10-12_22-10-0112.10.2025weekly
6cyberpanel-home-2025-10-19_22-10-0119.10.2025weekly
7cyberpanel-home-2025-10-26_12-10-0126.10.2025weekly
8cyberpanel-home-2025-11-09_20-10-0109.11.2025weekly
9cyberpanel-home-2025-11-16_22-10-0116.11.2025weekly
10cyberpanel-home-2025-11-23_22-10-0123.11.2025weekly
11cyberpanel-home-2025-11-30_22-10-0130.11.2025weekly
12cyberpanel-home-2025-12-07_22-10-0107.12.2025weekly
13cyberpanel-home-2025-12-14_22-10-0114.12.2025weekly
14cyberpanel-home-2025-12-21_22-10-0121.12.2025weekly
15cyberpanel-home-2025-12-28_22-10-0128.12.2025weekly
16cyberpanel-home-2026-01-04_22-10-0104.01.2026weekly
17cyberpanel-home-2026-01-11_22-10-0111.01.2026weekly
18cyberpanel-home-2026-01-18_22-10-0118.01.2026weekly
19cyberpanel-home-2026-01-25_22-10-0225.01.2026weekly
20cyberpanel-home-2026-02-01_22-10-0101.02.2026weekly
21cyberpanel-home-2026-02-08_22-10-0108.02.2026weekly
22cyberpanel-home-2026-02-15_22-10-0115.02.2026weekly
23cyberpanel-home-2026-02-16_22-10-0116.02.2026daily
24-28cyberpanel-home-2026-02-17 … 02-2117-21.02daily
29-52cyberpanel-home-2026-02-22 … 02-2422-24.022h

05 — Стратегия

🎯

Основна идея

Бекъпите продължават да се правят на s12 както до сега. Веднъж дневно, нов архив се push-ва и към s1-backups (отделно borg repo). На s12 се пазят само последните 7 дни — по-старите се трият. На s1 всичко си остава — пълна история. При restore, менюто показва всички архиви от двете места — от което избереш, от него възстановява.

Как работи системата

s12 / cyberpanel

Borg create на /home
Всеки 2 часа

Локален Borg repo

/var/backups/borg-home
Само последната седмица
~20 архива, ~50-80 GB

веднъж дневно (04:00) — borg create през SSH

s1-backups

/backups/cyberpanel/borg-home
Пълна история (месеци / години)
40 TB налични

restore (borg extract)

backup-manager.sh

Показва [LOCAL] + [S1] архиви
Избираш → възстановява от съответното

Защо два repo-та?

Borg repo не може да се rsync-не и после да се prune-не различно на двете места. Ако rsync-неш с --delete и после prune-неш на s12, при следващия rsync старите архиви се трият и от s1. Без --delete пък се трупат orphan chunks и repo-то на s1 се разваля.

Затова: две отделни borg repo-та, всяко със своя retention. Бекъпът е един (прави се на s12), но се push-ва и към s1 като независим архив. Така на s12 можеш свободно да триеш стари архиви, а на s1 те си остават.

s12 (локално)s1-backups (remote)
Какво еБърз кеш на бекъпиДългосрочен архив
Архиви~20 (последната седмица)Всички — пълна история
Retentionkeep-within 2d + keep-daily 7keep-daily 30 + keep-weekly 52 + keep-monthly 12
Размер на repo~50-80 GB~300+ GB (расте)
Честота на бекъпВсеки 2 часаВеднъж дневно (04:00)
Скорост на restoreБързо (локален диск)По-бавно (през SSH/мрежа)
Диск2 TB (95% → ~85%)40 TB (0.5%)

Преди / След

Сега

  • • 52 архива на s12 — 291 GB
  • • Диск 95% пълен
  • • Нула off-site бекъпи
  • • Ако s12 умре — всичко е загубено
  • • Remote скриптове — всички счупени

След промените

  • • ~20 архива на s12 — ~60 GB
  • • Диск спада до ~85%
  • • Пълна история на s1 (40 TB)
  • • Ако s12 умре — restore от s1
  • • Unified меню — виждаш всичко

06 — Стъпки за изпълнение

  1. Инсталиране на Borg на s1-backups

    Контейнерът е Ubuntu на Incus, стандартен apt install.

    ssh root@s1-backups apt update && apt install borgbackup -y borg --version
  2. SSH ключ от s12/cyberpanel → s1-backups

    Cyberpanel контейнерът вече има ed25519 ключ. Копираме го към s1-backups.

    # От s12, вътре в cyberpanel контейнера: ssh-copy-id -i ~/.ssh/id_ed25519 root@s1-backups # Тест: ssh root@s1-backups hostname # трябва да каже: backups
  3. Създаване на Borg repo на s1-backups

    Без криптиране — същото като локалния repo за лесен достъп.

    # На s1-backups: mkdir -p /backups/cyberpanel borg init --encryption=none /backups/cyberpanel/borg-home
  4. Първоначален трансфер: push на всички текущи 52 архива към s1

    Вместо rsync, правим borg create от s12 към s1 repo-то. Но за първоначалния трансфер на всички 52 архива, rsync е по-бързо (после repo-то на s1 става самостоятелно и получава нови архиви чрез borg create).

    # Еднократно! От cyberpanel на s12: rsync -avz --progress \ -e "ssh -i /root/.ssh/id_ed25519" \ /var/backups/borg-home/ \ root@s1-backups:/backups/cyberpanel/borg-home/ # Проверка (от s1-backups): borg list /backups/cyberpanel/borg-home # трябва да покаже 52 архива
  5. Нов скрипт: borg-push-to-s1.sh

    Веднъж дневно прави borg create от s12 директно в repo-то на s1 през SSH. Плюс щаден borg prune за s1 (пази много повече).

    #!/usr/bin/env bash — /root/scripts/backup/borg-push-to-s1.sh S1_REPO="ssh://root@s1-backups/backups/cyberpanel/borg-home" # 1. Създаване на архив в s1 repo borg create --verbose --stats --compression zstd,8 \ --exclude '**/node_modules/**' \ --exclude '**/.cache/**' \ --exclude '**/wp-content/cache/**' \ ... (същите excludes) \ "$S1_REPO"::cyberpanel-home-{now:%Y-%m-%d_%H-%M-%S} \ /home # 2. Prune на s1 (щаден — пази дълга история) borg prune -v --list "$S1_REPO" \ --keep-daily=30 \ --keep-weekly=52 \ --keep-monthly=12 # 3. Compact borg compact "$S1_REPO"
  6. Промяна на prune на s12 — само последната седмица

    САМО след като стъпки 1-5 са завършени и проверени! Махаме --keep-weekly=52.

    # В borg-home-local.sh — променяме реда с prune: # Старо: borg prune -v --list "$BORG_REPO" --keep-within=2d --keep-daily=7 --keep-weekly=52 # Ново: borg prune -v --list "$BORG_REPO" --keep-within=2d --keep-daily=7
  7. Обновяване на backup-manager.sh — unified restore

    Менюто показва архиви от двата repo-та. Избираш номер → системата знае от кой repo да restore-не.

    # backup-manager.sh добавя втори repo: LOCAL_REPO="/var/backups/borg-home" S1_REPO="ssh://root@s1-backups/backups/cyberpanel/borg-home" # List: показва от двата # Restore: по номер определя кой repo # WP DB restore работи идентично и в двата случая
  8. Нов Cron

    Добавяме само един нов ред за ежедневния push към s1.

    0 */2 * * * /root/scripts/backup/wp-export-all-db.sh # DB export (2h) 10 */2 * * * /root/scripts/backup/borg-home-local.sh # Local borg (2h) 0 4 * * * /root/scripts/backup/borg-push-to-s1.sh # НОВ: Push to s1 (1/ден)

07 — Нов Cron график

Всеки 2 часа

:00
wp-export-all-db.sh
WP DB dump

Всеки 2 часа

:10
borg-home-local.sh
Local borg + prune (7 дни)

Веднъж дневно

04:00
borg-push-to-s1.sh
Push to s1 + prune (пълна история)

Бекъп хронология: DB export → (10 мин пауза) → Borg create + prune (локално) → (в 04:00) → Borg push to s1

08 — Как се възстановява

💡

Единно меню — виждаш всичко, от което избереш, от него възстановява

backup-manager.sh автоматично списява архивите от двата repo-та. Маркира ги [LOCAL] или [S1]. Ти избираш номер — системата знае от кой repo да извлече. WP DB restore работи идентично и в двата случая.

$ /root/scripts/backup/backup-manager.sh =========================== Web Factor Backup Menu =========================== 1) Make backup (DB export + File Backup) 2) List backups 3) Restore from backup q) Quit Select an option: 3 == LOCAL archives (s12 — последната седмица) == 1) cyberpanel-home-2026-02-24_08-10-01 2026-02-24 08:10 [LOCAL] 2) cyberpanel-home-2026-02-24_06-10-01 2026-02-24 06:10 [LOCAL] 3) cyberpanel-home-2026-02-24_04-10-01 2026-02-24 04:10 [LOCAL] ... 19) cyberpanel-home-2026-02-17_22-10-01 2026-02-17 22:10 [LOCAL] 20) cyberpanel-home-2026-02-16_22-10-01 2026-02-16 22:10 [LOCAL] == REMOTE archives (s1 — пълна история) == 21) cyberpanel-home-2026-02-24_04-00-00 2026-02-24 04:00 [S1] 22) cyberpanel-home-2026-02-23_04-00-00 2026-02-23 04:00 [S1] 23) cyberpanel-home-2026-02-22_04-00-00 2026-02-22 04:00 [S1] ... 48) cyberpanel-home-2025-10-05_22-10-01 2025-10-05 22:10 [S1] 49) cyberpanel-home-2025-09-28_22-10-01 2025-09-28 22:10 [S1] 50) cyberpanel-home-2025-09-21_22-10-01 2025-09-21 22:10 [S1] 51) cyberpanel-home-2025-09-17_06-11-51 2025-09-17 06:11 [S1] Choose archive number (1-51): 48 Selected: cyberpanel-home-2025-10-05_22-10-01 [S1] Restore INTO (ABS path, e.g. /home/site/public_html/wp-content): /home/mysite.com/public_html/wp-content Wipe target contents: /home/mysite.com/public_html/wp-content Extract cyberpanel-home-2025-10-05_22-10-01 -> home/mysite.com/public_html/wp-content (to /tmp/borg-restore-xxxxx) rsync --delete /tmp/.../ -> /home/mysite.com/public_html/wp-content/ File restore OK. DB: WP root -> /home/mysite.com/public_html DB: SQL -> /home/mysite.com/public_html/wp-content/db-mysite.com.sql DB: restore OK.

Ръчен restore (без менюто)

От s12 (последната седмица)

# Лист borg list /var/backups/borg-home # Restore cd / borg extract \ /var/backups/borg-home::archive-name \ home/site.com/public_html/wp-content
🌐

От s1 (пълна история)

S1=ssh://root@s1-backups/backups/cyberpanel/borg-home # Лист borg list "$S1" # Restore cd / borg extract \ "$S1"::archive-name \ home/site.com/public_html/wp-content
🔒

Ред на действие — нищо не се трие преди проверка

1) Инсталираме borg на s1 → 2) Копираме всички 52 архива от s12 на s1 → 3) Проверяваме: borg list на s1 показва 52 архива → 4) Тестваме restore от s1 → 5) Чак тогава сменяме prune на s12 да пази само 7 дни → 6) Пускаме ежедневния push в cron. Старите скриптове (backup-home-borg.sh, borg-oneliner.sh и др.) остават непокътнати.