Files
itpp-infrastructure/backup-plan.md
T
root fcc9863232 Update backup plan doc with Jul 28 migration changes
- Remove stale core-services (Vaultwarden, Twenty, SearXNG, Komodo)
- Add new App1 services (Komodo, DocuSeal, Twenty CRM backups)
- Update S3 path table with canonical locations
- Add migration history section (Jul 28)
- Note stale core/ subfolder paths in S3 for reference
- Coverage: 26 backup targets across 6 servers + router
2026-07-28 20:51:48 -04:00

216 lines
12 KiB
Markdown

# ITPP Backup Plan
> **Last updated:** 2026-07-28
> **Scope:** All ITPP infrastructure backups — Hermes core, application servers, routers, and external services.
> **Storage:** Wasabi S3 (us-east-1) via `--endpoint-url https://s3.us-east-1.wasabisys.com`
> **Cron backend:** Hybrid — system crontab + Hermes cron jobs
---
## Backup Inventory (26 targets)
### Core (152.53.192.33) — RS 2000
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| Hermes Agent (full) | `hermes-backup.sh` — tar.gz of config, skills, profiles, sessions | `s3://hermes-vps-backups/hermes-full-backup/` | 1:00 AM | 2026-07-28 |
| Hermes Live Sync | `hermes-live-sync` cron — session state + profiles DB | `s3://hermes-vps-backups/live/` | Every 15 min | 2026-07-28 20:42 |
| /root Essentials | `root-essentials-backup.sh` — dotfiles, keys, scripts | `s3://hermes-vps-backups/root-backup/` | 3:00 AM | 2026-07-28 |
| Grafana | `core-services-backup.sh` — SQLite DB dump | `s3://hermes-vps-backups/core/grafana/` | 1:30 AM | 2026-07-28 |
| Uptime Kuma | `core-services-backup.sh` — SQLite DB dump | `s3://hermes-vps-backups/core/uptime-kuma/` | 1:30 AM | 2026-07-28 |
| Docker Volumes | `core-services-backup.sh` — tar of key compose volumes | `s3://hermes-vps-backups/volumes/` | 1:30 AM | 2026-07-28 |
| Prometheus | `core-services-backup.sh` — TSDB snapshot | `s3://hermes-vps-backups/core/prometheus/` | 1:30 AM | 2026-07-28 |
### App1 (152.53.36.131) — RS 4000
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| Open WebUI | `app1-backup.sh` — data dir tar.gz | `s3://hermes-vps-backups/app1/openwebui/` | 2:00 AM | 2026-07-28 |
| LiteLLM | `litellm-backup.sh` — Postgres DB dump + .env | `s3://hermes-vps-backups/app1/litellm/` | 3:30 AM | 2026-07-28 |
| n8n | `app1-backup.sh` — Postgres DB dump | `s3://hermes-vps-backups/app1/n8n/` | 2:00 AM | 2026-07-28 |
| MCP Server Configs | `app1-backup.sh` — MCP settings files | `s3://hermes-vps-backups/app1/mcp/` | 2:00 AM | 2026-07-28 |
| Vaultwarden | `vaultwarden-backup.sh` — SQLite DB dump | `s3://hermes-vps-backups/app1/vaultwarden/` | 2:30 AM | 2026-07-28 |
| Komodo | `komodo-backup.sh` — MongoDB dump + compose + keys | `s3://hermes-vps-backups/app1/komodo/` | 3:45 AM | 2026-07-28 |
| DocuSeal | `docuseal-backup.sh` — SQLite DB + attachments | `s3://hermes-vps-backups/app1/docuseal/` | 4:00 AM | 2026-07-28 |
| Twenty CRM | `twenty-backup.sh` — Postgres dump + .env + compose | `s3://hermes-vps-backups/app1/twenty/` | 4:15 AM | 2026-07-28 |
| Kokoro TTS | *(stateless — no backup needed)* | — | — | — |
### App2 (152.53.39.202) — RS 4000
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| Hudu | `hudu-backup.sh` — Postgres dump | `s3://hermes-vps-backups/hudu/backups/` | 7:00 AM | 2026-07-28 |
| Gitea | `gitea-backup.sh` — repos + DB dump | `s3://hermes-vps-backups/gitea/daily/` | 8:00 AM | 2026-07-28 |
| UNMS | `unms-backup-sync.sh` — auto-backup .unms | `s3://hermes-vps-backups/unms-backups/live/backups/` | 6:00 AM | 2026-07-28 |
| UniFi | `unifi-backup-sync.sh` — auto-backup .unf | `s3://hermes-vps-backups/unifi-backups/` | 2:00 AM | 2026-07-18 |
| Traccar | `app2-backup.sh` — H2 DB + config | `s3://hermes-vps-backups/app2/traccar/` | 2:30 AM | 2026-07-28 |
### App3 (152.53.241.111) — RS 4000
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| CloudPanel DB | `app3-backup.sh` — SQLite DB | `s3://hermes-vps-backups/app3/cloudpanel/` | 3:00 AM | 2026-07-28 |
| MySQL (all DBs) | `app3-backup.sh` — mysqldump | `s3://hermes-vps-backups/app3/mysql/` | 3:00 AM | 2026-07-28 |
| WordPress Files | `app3-backup.sh` — wp-content tar.gz | `s3://hermes-vps-backups/app3/wordpress/` | 3:00 AM | 2026-07-28 |
| Nginx Configs | `app3-backup.sh` — sites-enabled + config | `s3://hermes-vps-backups/app3/config/` | 3:00 AM | 2026-07-28 |
| WordPress Snapshots | `/opt/backup-restore/snapshot.sh` — per-site tar.gz | `/opt/backup-restore/snapshots/` (local, 30-day retention) | 6 AM / 6 PM | 2026-07-28 13:00 |
### wphost02 (5.161.62.38) — Hetzner CPX21
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| WordPress (7 sites) | `ssh → /root/backup.sh` — per-site tar.gz + all DBs | `s3://hermes-vps-backups/wphost02-backup/` | 5:00 AM | 2026-07-28 |
### Home Router
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| MikroTik CCR2004 | `run-wisp-backup.sh` — export .rsc via SSH | `s3://mikrotik-ccr-backups/wisp-backups/configs/home/` | 6:00 AM | 2026-07-28 |
### External
| Service | Method | Destination | Schedule | Last Verified |
|---------|--------|-------------|----------|---------------|
| Hetzner Snapshots | `snapshot-hetzner.py` — API-driven disk snapshots | Hetzner Cloud (weekly) | Mon 5:00 AM | — |
---
## Schedules Summary (ET)
| Time | What | Runner | Script |
|------|------|--------|--------|
| Every 15 min | Hermes session state | Hermes cron | `hermes-live-sync` |
| 1:00 AM | Full Hermes backup | crontab | `hermes-backup.sh` |
| 1:30 AM | Grafana, Uptime Kuma, Docker volumes, Prometheus | crontab | `core-services-backup.sh` |
| 2:00 AM | Open WebUI, n8n, MCP configs (App1) | crontab | `app1-backup.sh` |
| 2:30 AM | Vaultwarden (App1) + Traccar (App2) | Hermes cron / crontab | `vaultwarden-backup.sh`, `app2-backup.sh` |
| 3:00 AM | /root essentials + App3 (CloudPanel, MySQL, WP, Nginx) | crontab | `root-essentials-backup.sh`, `app3-backup.sh` |
| 3:30 AM | LiteLLM (App1) | Hermes cron | `litellm-backup.sh` |
| 3:45 AM | Komodo (App1) | Hermes cron | `komodo-backup.sh` |
| 4:00 AM | DocuSeal (App1) | Hermes cron | `docuseal-backup.sh` |
| 4:15 AM | Twenty CRM (App1) | Hermes cron | `twenty-backup.sh` |
| 5:00 AM | wphost02 WordPress (SSH) | crontab | `wphost02-backup` |
| 6:00 AM | MikroTik CCR + UNMS sync | Hermes cron | `run-wisp-backup.sh`, `unms-backup-sync.sh` |
| 6 AM / 6 PM | WordPress per-site snapshots (App3, local) | App3 crontab | `/opt/backup-restore/snapshot.sh` |
| 7:00 AM | Hudu (App2) | Hermes cron | `hudu-backup.sh` |
| 8:00 AM | Gitea (App2) | Hermes cron | `gitea-backup.sh` |
| Mon 5:00 AM | Hetzner weekly snapshots | Hermes cron | `snapshot-hetzner.py` |
---
## Script Inventory
### On Core (`/root/.hermes/scripts/`)
| Script | Purpose | Runs |
|--------|---------|------|
| `hermes-backup.sh` | Full Hermes tar.gz to S3 | crontab 1:00 AM |
| `core-services-backup.sh` | Grafana, Uptime Kuma, volumes, Prometheus | crontab 1:30 AM |
| `root-essentials-backup.sh` | /root keys, configs, scripts | crontab 3:00 AM |
| `backup-audit-check.sh` | Verify recent backup timestamps | crontab 2:00 AM |
| `vaultwarden-backup.sh` | Vaultwarden SQLite dump (SSH to App1) | Hermes cron 2:30 AM |
| `litellm-backup.sh` | LiteLLM Postgres dump + config (SSH to App1) | Hermes cron 3:30 AM |
| `komodo-backup.sh` | Komodo MongoDB dump (SSH to App1) | Hermes cron 3:45 AM |
| `docuseal-backup.sh` | DocuSeal SQLite + attachments (SSH to App1) | Hermes cron 4:00 AM |
| `twenty-backup.sh` | Twenty CRM Postgres dump (SSH to App1) | Hermes cron 4:15 AM |
| `app1-backup.sh` | Open WebUI, n8n, MCP configs (SSH to App1) | App1 crontab 2:00 AM |
| `app2-backup.sh` | Traccar backup (SSH to App2) | App2 crontab 2:30 AM |
| `app3-backup.sh` | CloudPanel, MySQL, WP, Nginx (SSH to App3) | crontab 3:00 AM |
| `wphost02-backup.sh` | SSH to wphost02, backup all sites | crontab 5:00 AM |
| `run-wisp-backup.sh` | MikroTik CCR config export | Hermes cron 6:00 AM |
| `unms-backup-sync.sh` | UNMS auto-backup sync to S3 | Hermes cron 6:00 AM |
| `unifi-backup-sync.sh` | UniFi auto-backup sync to S3 | Hermes cron 2:00 AM |
| `hudu-backup.sh` | Hudu Postgres dump to S3 | Hermes cron 7:00 AM |
| `gitea-backup.sh` | Gitea repos + DB dump to S3 | Hermes cron 8:00 AM |
| `snapshot-hetzner.py` | Hetzner server disk snapshots via API | Hermes cron Mon 5:00 AM |
### On App3 (`/opt/backup-restore/`)
| Script | Purpose | Runs |
|--------|---------|------|
| `snapshot.sh` | Per-site WordPress tarball + DB | App3 crontab 6 AM / 6 PM |
### On wphost02 (`/root/`)
| Script | Purpose | Runs |
|--------|---------|------|
| `backup.sh` | All 7 WordPress sites + all MySQL DBs | Triggered via SSH from Core |
---
## S3 Bucket Structure
```
hermes-vps-backups/
├── hermes-full-backup/ — Full Hermes daily (tar.gz)
├── live/ — Hermes live sync (every 15 min)
├── live-sync/ — Old sync format (deprecated)
├── root-backup/ — /root essentials
├── standby/ — Standby configs + recovery bundle
├── core/
│ ├── grafana/ — Grafana SQLite DB
│ ├── uptime-kuma/ — Uptime Kuma SQLite DB
│ ├── prometheus/ — Prometheus TSDB snapshots
│ ├── vaultwarden/ — [STALE — service migrated to App1]
│ ├── twenty/ — [STALE — service migrated to App1]
│ ├── searxng/ — [STALE — service removed]
│ └── komodo/ — [STALE — service migrated to App1]
├── app1/
│ ├── openwebui/ — Open WebUI data
│ ├── litellm/ — LiteLLM Postgres dump + config
│ ├── n8n/ — n8n Postgres dump
│ ├── mcp/ — MCP server configs
│ ├── vaultwarden/ — Vaultwarden SQLite dump
│ ├── komodo/ — Komodo MongoDB dump
│ ├── docuseal/ — DocuSeal SQLite + attachments
│ └── twenty/ — Twenty CRM Postgres dump
├── app2/
│ └── traccar/ — Traccar H2 DB + config
├── app3/
│ ├── cloudpanel/ — CloudPanel SQLite DB
│ ├── mysql/ — All MySQL DBs
│ ├── wordpress/ — wp-content tar.gz
│ └── config/ — Nginx configs
├── hudu/backups/ — Hudu Postgres dump
├── gitea/daily/ — Gitea repos + DB
├── unms-backups/live/ — UNMS auto-backups
├── unifi-backups/ — UniFi controller backups
├── wphost02-backup/ — wphost02 per-site + DB
├── volumes/ — Docker volume dumps
├── caddy/ — (unused)
├── assets/ — Static assets
├── snapshots/ — (unused)
└── system-configs-*.tar.gz — Historical system config snapshots
mikrotik-ccr-backups/
└── wisp-backups/configs/
└── home/ — CCR2004 export .rsc
```
---
## Migration History (Jul 28, 2026)
All the following services were migrated from Core to App1 in a single session:
| Service | Old Home | New Home | Backup Before | Backup After |
|---------|----------|----------|--------------|-------------|
| Vaultwarden | Core (:8080) | App1 (:8081) | `core/vaultwarden/` (stale) | `app1/vaultwarden/` ✅ |
| SearXNG | Core (:8888) | Removed | `core/searxng/` (stale) | N/A (replaced by Super Search) |
| Twenty CRM | Core (:3003) | App1 (:3003) | `core/twenty/` (stale) | `app1/twenty/` ✅ |
| Komodo | Core (:9120) | App1 (:9120) | `core/komodo/` (stale) | `app1/komodo/` ✅ |
| DocuSeal | Core (:3000) | App1 (:3002) | No backup existed | `app1/docuseal/` ✅ |
| Kokoro TTS | Core (:8880) | App1 (:8880) | N/A (stateless) | N/A (stateless) |
---
## Disaster Recovery
- **Live Hermes:** netcup VPS — `core.itpropartner.com``152.53.192.33`
- **Standby Hermes:** Hetzner CPX21 — `app1-bu.itpropartner.com``5.161.225.131`
- Cron checks live box every 10 min, takes over if down
- Auto-restores from `s3://hermes-vps-backups/hermes-full-backup/`
- Provider diversity: netcup outage won't kill both Core and standby
- **Recovery priority:** Hermes first → infrastructure monitoring (Uptime Kuma, Grafana) → App1 services → App2 services
- **24 backup scripts** on Core, 1 on App3, 1 on wphost02