# Backup Project ## 📋 Co je tento projekt Zálohovací skripty pro domácí serverové infrastruktuře — dva Unraid servery (Tower, Tower1). Skripty běží jako **Unraid User Scripts** spouštěné automaticky každý den ve **4:40 ráno**. --- ## 🗂️ Struktura projektu ``` Backup/ ├── MongoDBBackup/ │ ├── mongodbbackup_with_gzip.sh ← záloha DB (mongodump --archive --gzip) │ ├── mongodbrestore_from_backup.sh ← restore ze zálohy (mongorestore) │ └── verify_backup_integrity.sh ← ověření po restore (mongosh) │ ├── PostGRESQLTower/ │ ├── postgresqlbackup_with_gzip.sh ← záloha PG18 (pg_dumpall → gzip) │ ├── postgresqlimmichbackup_with_gzip.sh ← záloha PG Immich (pg_dumpall → gzip) │ ├── postgresqlrestore_from_backup.sh ← restore PG18 (gunzip → psql) │ └── verify_backup_integrity.sh ← ověření po restore (psql) │ ├── GiteaBackup/ │ └── gitea_backup.sh ← záloha appdata (docker stop → tar.gz → start) │ ├── KanboardBackup/ │ └── kanboard_backup.sh ← záloha appdata (docker stop → tar.gz → start) │ └── MicrobinBackup/ └── microbin_backup.sh ← záloha appdata (docker stop → tar.gz → start) ``` --- ## ⚙️ Jak fungují zálohy — dva vzory ### Vzor A — databázový dump (MongoDB, PostgreSQL) Záloha běží **za chodu** kontejneru — dump streamuje přes stdout přímo na disk hostitele, bez volume mountu a bez dočasné kopie uvnitř kontejneru. ``` docker exec kontejner nástroj-pro-dump → (pipe) → soubor na hostiteli ``` - **MongoDB:** `mongodump --archive --gzip` → `admin.archive.gz`, `edc.archive.gz` - **PostgreSQL 18:** `pg_dumpall | gzip` → `all_databases.sql.gz` - **PostgreSQL Immich:** `pg_dumpall | gzip` → `immich_all.sql.gz` ### Vzor B — appdata archiv (Gitea, Kanboard, Microbin) Záloha probíhá **při zastaveném kontejneru** — soubory nesmí být zapisovány v průběhu `tar`. ``` docker stop → tar -czf appdata/kontejner → docker start ``` Kontejner se nastartuje **vždy**, i při chybě archivu — minimální downtime. --- ## 🔄 Rotace záloh | Záloha | Metoda | Zachovává | |--------|--------|-----------| | MongoDB | dvoustupňová (stáří + count) | 3 dny / 3 zálohy | | PostgreSQL 18 | dvoustupňová (stáří + count) | 7 dní / 7 záloh | | PostgreSQL Immich | dvoustupňová (stáří + count) | 7 dní / 7 záloh | | Gitea | podle stáří | 7 dní | | Kanboard | podle stáří | 7 dní | | Microbin | podle stáří | 7 dní | Dvoustupňová rotace: nejprve smaž dle stáří, pak ořízni na max. count. To garantuje minimum záloh i při přerušeném schedule. --- ## 🚨 Restore — důležité poznámky - **PostgreSQL Immich**: vyžaduje při restore **stejný Docker image** (`tensorchord/pgvecto-rs:pg16-v0.2.0`) kvůli pgvecto-rs extension. Standardní postgres:16 nebude fungovat. - **Kanboard**: appdata + MySQL záloha zvlášť (MySQL skript zálohuje DB `kanboard`). - **MongoDB restore**: používá `--drop` — smaže kolekce před obnovením. Vědomá akce. - **PostgreSQL restore**: chybové hlášky "role already exists" jsou normální (dump je idempotentní). --- ## 🛠️ Nasazení skriptu na Tower ```python import paramiko client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('192.168.1.76', username='root', password='7309208104', look_for_keys=False, allow_agent=False) sftp = client.open_sftp() sftp.put('lokalní_skript.sh', '/boot/config/plugins/user.scripts/scripts/NázevSkriptu/script') client.exec_command('chmod +x /boot/config/plugins/user.scripts/scripts/NázevSkriptu/script') ``` Schedule se nastavuje v `/boot/config/plugins/user.scripts/schedule.json`. --- # Backup Project - Infrastructure Info ## 🖥️ Servery | Server | Hostname | IP | OS | |--------|----------|----|----| | Tower | tower / tower.lan | 192.168.1.76 | Unraid | | Tower1 | tower1 | 192.168.1.50 | Unraid | --- ## 🔐 SSH přístup **Credentials:** | Server | User | Password | |--------|------|----------| | Tower | `root` | `7309208104` | | Tower1 | `root` | `Vlado7309208104++` | **Připojení:** ```bash ssh root@192.168.1.76 # Tower ssh root@192.168.1.50 # Tower1 ``` **Důležité:** Tower a Tower1 mají vzájemně nahrané SSH klíče - Tower1 se může připojit na Tower bez hesla a naopak. **Připojení z Pythonu (Windows):** Použít `look_for_keys=False, allow_agent=False` — jinak selže kvůli "Too many authentication failures": ```python client.connect("192.168.1.76", username="root", password="7309208104", look_for_keys=False, allow_agent=False) ``` --- ## 🐳 Docker kontejnery | Server | Kontejner | Port | Popis | |--------|-----------|------|-------| | Tower | `MongoDB` | 27017 | MongoDB 8.2.9 | | Tower1 | `MongoDB` | 27017 | MongoDB 8.2.9 | | Tower | `MySQL` | 3306 | MySQL | | Tower | `postgresql18` | 5432 | PostgreSQL 18 (hlavní) | | Tower | `PostgreSQL_Immich` | 5433→5432 | PostgreSQL 16 + pgvecto-rs (Immich) | | Tower | `immich` | 8888→8080 | Immich (foto server) | --- ## 📁 Důležité cesty ### Tower | Co | Cesta | |----|-------| | MongoDB zálohy | `/mnt/user/Backup/Critical/MongoDBBackup/` | | MySQL zálohy | `/mnt/user/MySQLBackup/` | | PostgreSQL zálohy | `/mnt/user/Backup/Critical/PostgreSQLBackup/` | | PostgreSQL Immich zálohy | `/mnt/user/Backup/Critical/PostgreSQLImmichBackup/` | | PostgreSQL 18 data | `/mnt/user/appdata/postgresql18` | | PostgreSQL Immich data | `/mnt/user/appdata/PostgreSQL_Immich` | | Kanboard zálohy | `/mnt/user/Backup/Critical/KanboardBackup/` | | Microbin zálohy | `/mnt/user/Backup/Critical/MicrobinBackup/` | | User Scripts | `/boot/config/plugins/user.scripts/scripts/` | | Test share | `/mnt/user/#test/` | ### Windows (lokální) | Co | Cesta | |----|-------| | MongoDB zálohy | `\\tower\Backup\Critical\MongoDBBackup\` | | MySQL zálohy | `\\tower\MySQLBackup\` | | PostgreSQL zálohy | `\\tower\Backup\Critical\PostgreSQLBackup\` | | PostgreSQL Immich zálohy | `\\tower\Backup\Critical\PostgreSQLImmichBackup\` | | Kanboard zálohy | `\\tower\Backup\Critical\KanboardBackup\` | | Microbin zálohy | `\\tower\Backup\Critical\MicrobinBackup\` | | Test share | `\\tower1\#test\` | --- ## 🗄️ MongoDB - **Verze:** 8.2.9 - **Auth:** Žádná (otevřené) - **Databáze k zálohování:** `admin`, `edc` (+ další dle skriptu) - **Připojení z Pythonu:** ```python from pymongo import MongoClient client = MongoClient('mongodb://192.168.1.76:27017') # Tower client = MongoClient('mongodb://192.168.1.50:27017') # Tower1 ``` --- ## 🗄️ MySQL - **User:** `root` - **Password:** `Vlado9674+` - **Databáze:** `fio`, `torrents`, `OrdinaceDropBoxBackup`, `medevio`, `kanboard`, `medicus`, `studie`, `puzzle` --- ## 📜 User Scripts na Tower (Unraid) | Název | Popis | Schedule | |-------|-------|----------| | `3_MYSQL_BACKUP_WITH_GZIP` | MySQL backup všech DB | Daily | | `MongoDBBackupWithGzip` | MongoDB backup (`--archive --gzip`) | Daily | | `PostgreSQLBackup` | PostgreSQL 18 backup (`pg_dumpall` → gzip) | Daily | | `PostgreSQLImmichBackup` | PostgreSQL Immich backup (`pg_dumpall` → gzip) | Daily | | `GiteaBackup` | Gitea backup (`docker stop` → `tar.gz` appdata → `docker start`) | Daily | | `KanboardBackup` | Kanboard backup (`docker stop` → `tar.gz` appdata → `docker start`) | Daily | | `MicrobinBackup` | Microbin backup (`docker stop` → `tar.gz` appdata → `docker start`) | Daily | **Schedule `daily` = spuštění ve 4:40 ráno** (přes `/etc/cron.daily`, crontab: `40 4 * * *`) **Schedule config:** `/boot/config/plugins/user.scripts/schedule.json` — zde Unraid ukládá frequency pro každý User Script. Kontejner Gitea se na Tower jmenuje `Gitea` (s velkým G). ## 📜 User Scripts na Tower1 (Unraid) | Název | Popis | |-------|-------| | `MONGODB_RESTORE` | Restore edc DB z Tower přes SSH stream | --- ## 🗄️ PostgreSQL ### Instance 1 — postgresql18 (hlavní) - **Verze:** 18 - **Port:** 5432 - **User:** `vladimir.buzalka` - **Password:** `Vlado7309208104++` - **Auth:** Heslo (PGPASSWORD env var) - **Záloha:** `pg_dumpall` → `/mnt/user/Backup/Critical/PostgreSQLBackup/tower/` - **Dump size:** ~3.3 GB, čas ~3 min ### Instance 2 — PostgreSQL_Immich (Immich foto server) - **Verze:** 16 + pgvecto-rs extension (image: `tensorchord/pgvecto-rs:pg16-v0.2.0`) - **Port:** 5433 (host) → 5432 (container) - **User:** `postgres` - **Password:** `postgres` - **DB:** `immich` - **Záloha:** `pg_dumpall` → `/mnt/user/Backup/Critical/PostgreSQLImmichBackup/tower/` - **Dump size:** ~52 MB, čas ~18 sec - **Restore pozor:** Vyžaduje stejný image s pgvecto-rs extension!