Added updated README.md for the new code base.

This commit is contained in:
2026-02-11 14:27:45 +01:00
parent 66ae90611a
commit cb7891337e

403
README.md
View File

@@ -1,113 +1,340 @@
# app-backup (Rocky Linux / Apache / Postfix)
# app-backup (Rocky Linux 10) Split-Backups für WordPress, Nextcloud, Gitea + DBs (OneDrive/rclone)
Resiliente tägliche Backups für **WordPress**, **Nextcloud** und **Mail** (Postfix/Dovecot optional).
Erzeugt **timestamped Archive**, lädt nach **OneDrive** via **rclone** und verschickt einen **Mail-Report** an den lokalen User **johannes**.
Dieses Repo enthält ein **Backup- und Restore-Setup** für typische Self-Hosted-Apps auf Rocky Linux 10:
Enthält zusätzlich ein Restore-Script mit **Dry-Run**, **Service-Stop/Start** und **Nextcloud Maintenance Mode**.
- **WordPress** (Webroot)
- **Nextcloud** (Code + Data getrennt; Data liegt bei uns unter `.../nextcloud/data`)
- **Gitea** (native Installation via systemd + MariaDB)
- **MariaDB-Dumps** (WordPress DB, Nextcloud DB, Gitea DB)
- Upload nach **OneDrive** per **rclone**
## Installation
Neu in dieser Version: **kein riesiges “Alles-in-eins”-Archiv** mehr, sondern **sauber getrennte Archives pro Komponente**. Das macht Uploads stabiler (große Dateien), Restore selektiver und Fehler leichter eingrenzbar.
Pakete:
```bash
sudo dnf install -y rsync tar zstd gzip rclone mariadb postfix
---
## ✅ Ziele / Designentscheidungen
### 1) Split statt „dickes Archiv“
Es werden pro Lauf mehrere Archive erzeugt (zstd oder gzip):
- `..._meta.tar.zst` Meta (Timestamp, Hostname, Größeninfos)
- `..._db.tar.zst` DB Dumps (SQL Dateien)
- `..._wordpress.tar.zst` WordPress Webdaten (ohne Nextcloud-Unterordner)
- `..._nextcloud.tar.zst` Nextcloud **Code/Web** (mit Exclude `data/`)
- `..._nextcloud-data.tar.zst` Nextcloud **Data** separat
- `..._gitea.tar.zst` Gitea Data (APP_DATA_PATH)
- `..._gitea-etc.tar.zst` `/etc/gitea` (Gitea config)
Vorteile:
- Upload stabiler bei **1218 GB** (nicht 1 Monolith)
- Restore selektiv (z.B. nur DB, nur Nextcloud-data, …)
- Fehlerbehebung leichter (ein Archiv kaputt → nicht alles kaputt)
### 2) Nextcloud data unterhalb von `NC_DIR`
Bei uns liegt Nextcloud so:
- `NC_DIR=/var/www/html/nextcloud` (Code)
- `NC_DATA_DIR=/var/www/html/nextcloud/data` (Data)
Damit **Data nicht doppelt** gesichert wird:
- Beim Backup von `NC_DIR` wird `data/` **explizit ausgeschlossen** (`rsync --exclude data/`).
- Danach wird `NC_DATA_DIR` als eigenes Paket gesichert.
### 3) WordPress liegt im Webroot `/var/www/html` und Nextcloud als Unterordner
Bei uns liegt:
- WordPress im `WP_DIR=/var/www/html`
- Nextcloud in `/var/www/html/nextcloud`
Damit Nextcloud nicht im WP-Archiv landet:
- WP-Backup schließt `nextcloud/` automatisch aus, wenn `NC_DIR` genau `WP_DIR/nextcloud` ist.
### 4) rclone / OneDrive robust für große Dateien
Upload wird robust gemacht mit:
- Chunking: `--onedrive-chunk-size 64M`
- Timeouts: `--timeout 1h`, `--contimeout 30s`
- konservativ: `--transfers 2`, `--checkers 4`
- mehr Retries: `--retries 10`, `--low-level-retries 40`
Außerdem: **Remote-Namen sind case-sensitive!**
Remote ist bei uns z.B. `OneDrive:` (nicht `onedrive:`).
---
## 📦 Dateien & Pfade
### Skripte
- `app-backup.sh` → Backup erstellen, Archive erzeugen, optional Upload.
- `app-restore.sh` → Restore aus lokalem Ordner oder OneDrive-Run-Folder.
- `app-backup.conf` → Konfiguration (Pfad/Services/DB/Credentials).
### Zielpfade (Standard)
- Workdir: `/var/backups/app-backup`
- Archive: `/var/backups/app-backup/archives`
- Logs: `/var/log/app-backup`
### OneDrive Ziel (Beispiel)
Upload in:
```
OneDrive:Sicherung/JRITServerBackups/<hostname>/appbackup_<timestamp>/
```
Repo deploy:
---
## 🔧 Installation / Setup
### 1) Skripte installieren
Beispiel:
```bash
./install.sh
sudo install -d /etc/app-backup /usr/local/sbin
sudo install -m 0755 app-backup.sh /usr/local/sbin/app-backup.sh
sudo install -m 0755 app-restore.sh /usr/local/sbin/app-restore.sh
sudo install -m 0640 app-backup.conf /etc/app-backup/app-backup.conf
```
## Konfiguration
### 2) DB Credential Files anlegen
Für WordPress / Nextcloud / Gitea je eine `.cnf`.
Konfig anpassen:
- `/etc/app-backup/app-backup.conf`
Beispiele:
- `/etc/app-backup/db-wordpress.cnf`
- `/etc/app-backup/db-nextcloud.cnf`
- `/etc/app-backup/db-gitea.cnf`
DB-Credentials (aus Templates):
Inhalt:
```ini
[client]
user=backup
password=DEIN_PASSWORT
host=localhost
```
Rechte:
```bash
sudo cp /etc/app-backup/db-wordpress.cnf.example /etc/app-backup/db-wordpress.cnf
sudo cp /etc/app-backup/db-nextcloud.cnf.example /etc/app-backup/db-nextcloud.cnf
sudo chmod 600 /etc/app-backup/db-*.cnf
sudo chown root:root /etc/app-backup/db-*.cnf
sudo chmod 600 /etc/app-backup/db-*.cnf
```
rclone für root testen:
### 3) MariaDB Backup-User (Minimal-Rechte)
Pro DB (z.B. gitea):
```sql
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'DEIN_PASSWORT';
GRANT SELECT, SHOW VIEW, TRIGGER, EVENT, LOCK TABLES ON gitea.* TO 'backup'@'localhost';
FLUSH PRIVILEGES;
```
Optional: denselben User für wordpress/nextcloud verwenden, dann jeweils `GRANT ... ON wordpress.*` etc.
### 4) rclone Remote prüfen (Case-Sensitive!)
Auf dem Server (als derselbe User, der später rclone nutzt typischerweise root oder johannes):
```bash
rclone listremotes
rclone lsf "OneDrive:" --max-depth 1
rclone lsf "OneDrive:Sicherung" --max-depth 1
```
⚠️ Wichtig: Wenn das Backup als `root` läuft, muss `root` auch Zugriff auf die rclone config haben.
Typisch sind zwei Wege:
**Option A root nutzt eigene rclone config**
- `sudo rclone config` als root durchführen und Remote anlegen.
**Option B root nutzt Config von johannes**
- im Script/Service `RCLONE_CONFIG=/home/johannes/.config/rclone/rclone.conf` setzen
- oder in systemd Unit `Environment=RCLONE_CONFIG=...`
---
## ⚙️ Konfiguration: app-backup.conf (wichtige Stellen)
### OneDrive Remote Base
```bash
RCLONE_REMOTE_BASE="OneDrive:Sicherung/JRITServerBackups/$(hostname -s)"
```
Das Skript legt pro Run einen Unterordner an:
```bash
remote_run="${RCLONE_REMOTE_BASE}/appbackup_<timestamp>"
```
### WordPress / Nextcloud Layout (wichtig!)
```bash
WP_DIR="/var/www/html"
NC_DIR="/var/www/html/nextcloud"
NC_DATA_DIR="/var/www/html/nextcloud/data"
```
Damit wird:
- WordPress = alles in `/var/www/html` **ohne** `nextcloud/`
- Nextcloud Code = `/var/www/html/nextcloud` **ohne** `data/`
- Nextcloud Data = `/var/www/html/nextcloud/data` separat
### Gitea (native + MariaDB)
Aus deinem systemd/app.ini:
- `WorkingDirectory=/var/lib/gitea`
- `APP_DATA_PATH=/var/lib/gitea/data`
- config: `/etc/gitea/app.ini`
Daher:
```bash
ENABLE_GITEA="true"
GITEA_SERVICE_NAME="gitea"
ENABLE_GITEA_SERVICE_STOP="true"
GITEA_DATA_DIR="/var/lib/gitea/data"
GITEA_ETC_DIR="/etc/gitea"
GITEA_DB_NAME="gitea"
GITEA_DB_CNF="/etc/app-backup/db-gitea.cnf"
```
---
## ▶️ Backup ausführen
```bash
sudo /usr/local/sbin/app-backup.sh
```
Erwartetes Verhalten:
1) Lock `/run/app-backup.lock` verhindert Parallelruns
2) optional stoppt es Gitea kurz (konsistenter Snapshot)
3) Dumps: wordpress / nextcloud / gitea
4) rsync in staging
5) mehrere `.tar.zst` werden erzeugt
6) Upload pro Datei nach OneDrive (falls `ENABLE_UPLOAD=true`)
7) Remote retention (best effort)
8) lokale Retention löscht alte Archive
---
## ♻️ Restore ausführen
### Restore von OneDrive (Run-Ordnername angeben)
Du brauchst den Ordnernamen, z.B.:
`appbackup_2026-02-11_02-31-28`
Dann:
```bash
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_2026-02-11_02-31-28
```
### Restore aus lokalem Ordner
Wenn du die Archive lokal hast:
```bash
sudo /usr/local/sbin/app-restore.sh --local-run /var/backups/app-backup/archives/<run-folder>
```
### Dry-Run
```bash
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_... --dry-run
```
### Nur Files / nur DB
```bash
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_... --no-db
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_... --no-files
```
---
## 🧠 Restore-Details (was passiert danach?)
### Nextcloud
- Maintenance Mode wird optional aktiviert (konfigurierbar)
- Restore kopiert Code und Data getrennt zurück
- Danach:
- `occ maintenance:repair`
- optional `occ files:scan --all` (deaktiviert per default; kann lange dauern)
### Gitea
- Service wird optional gestoppt
- Data wird nach `GITEA_DATA_DIR` zurück synchronisiert
- `/etc/gitea` wird wiederhergestellt
- DB Dump wird importiert
- Service wird wieder gestartet
---
## 🧯 Troubleshooting
### 1) rclone Remote not reachable / “didn't find section in config file”
Typischer Fehler:
- Remote heißt `OneDrive:` aber Config nutzt `onedrive:`**case-sensitive**.
- Backup läuft als `root`, aber rclone config ist nur bei `johannes`.
Prüfen:
```bash
sudo rclone listremotes
sudo rclone lsd onedrive:
sudo -u johannes rclone listremotes
```
## Backup Timer
Fix:
- Entweder rclone remote auch für root konfigurieren,
- oder `RCLONE_CONFIG` auf johannes Config zeigen lassen.
Timer aktivieren (macht install.sh bereits):
### 2) Nextcloud Data doppelt oder fehlt
Stellen prüfen:
- `NC_DIR` korrekt?
- `NC_DATA_DIR` korrekt?
- Das Skript excludet `data/` bei Nextcloud Code. Data wird separat gesichert.
### 3) Große Uploads brechen ab
Setze z.B.:
- `RCLONE_TRANSFERS=1`
- `RCLONE_CHECKERS=2`
- `RCLONE_ONEDRIVE_CHUNK_SIZE=32M`
- optional `RCLONE_BWLIMIT="20M"`
### 4) Restore soll “hart” spiegeln
Standard ist vorsichtig (kein delete). Wenn du wirklich Ziel-Verzeichnisse exakt spiegeln willst:
```bash
RESTORE_STRICT_DELETE="true"
```
⚠️ Achtung: Das kann Dateien löschen, die nicht im Backup sind.
---
## 🗓️ Optional: systemd Service + Timer (Beispiel)
> Nur als Beispiel wenn ihr mögt, legen wir das als Files ins Repo.
`/etc/systemd/system/app-backup.service`
```ini
[Unit]
Description=app-backup
After=network.target mariadb.service
Wants=mariadb.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/app-backup.sh
```
`/etc/systemd/system/app-backup.timer`
```ini
[Unit]
Description=Run app-backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
```
Aktivieren:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now app-backup.timer
sudo systemctl list-timers | grep app-backup
```
Manueller Testlauf:
```bash
sudo systemctl start app-backup.service
journalctl -u app-backup.service -n 200 --no-pager
ls -la /var/log/app-backup/
ls -la /var/backups/app-backup/archives/
```
---
## Disk-Schutz / Retention (wichtig)
Um ein volllaufendes Dateisystem zu vermeiden, gilt:
- **Lokale Archive werden maximal `LOCAL_RETENTION_DAYS` Tage aufbewahrt** (Standard: **7 Tage**)
- Zusätzlich wird vor und nach dem Staging geprüft, ob mindestens **`MIN_FREE_GB` GiB** frei sind (Standard: **10 GiB**).
- Gelöschte Backups werden im **Mail-Report** aufgeführt (Anzahl + grob freigegebener Speicher).
Einstellungen in `/etc/app-backup/app-backup.conf`:
- `LOCAL_RETENTION_DAYS=7`
- `MIN_FREE_GB=10`
## Mail-Report
Versand per Postfix `/usr/sbin/sendmail` an `MAIL_TO` (Default: `johannes`).
Der Report enthält u.a.:
- Status (SUCCESS/FAIL), Laufzeit
- Was gesichert wurde + Größen
- Upload-Status (rclone)
- **Wie viele alte lokale Backups gelöscht wurden (Retention)**
## Restore (Wiederherstellung)
### Dry-Run (empfohlen)
```bash
sudo /usr/local/sbin/app-restore.sh --archive /var/backups/app-backup/archives/appbackup_YYYY-mm-dd_HH-MM-SS.tar.zst --dry-run
```
### Restore aus lokalem Archiv
```bash
sudo /usr/local/sbin/app-restore.sh --archive /var/backups/app-backup/archives/appbackup_YYYY-mm-dd_HH-MM-SS.tar.zst
```
### Restore direkt aus OneDrive (Download + Restore)
```bash
sudo /usr/local/sbin/app-restore.sh --remote-file appbackup_YYYY-mm-dd_HH-MM-SS.tar.zst
```
### Teil-Restore
Nur Nextcloud + DB:
```bash
sudo /usr/local/sbin/app-restore.sh --archive /path/to/archive.tar.zst --only nextcloud,nextcloud-data,db
```
Alles außer Mail:
```bash
sudo /usr/local/sbin/app-restore.sh --archive /path/to/archive.tar.zst --skip mail
```
### Nach dem Restore prüfen
```bash
systemctl status httpd postfix dovecot --no-pager
tail -n 200 /var/log/app-backup/app-restore_*.log
```
Optional (kann dauern):
```bash
sudo -u apache php /var/www/html/nextcloud/occ maintenance:repair
```
## ✅ Empfehlung: Restore-Test
Backups sind erst dann gut, wenn Restore getestet ist:
- Test-VM / Test-Host
- DB importieren
- Archive entpacken / rsync zurückspielen
- Nextcloud startet, Login klappt, Files sichtbar
- WordPress Frontend/Backend ok
- Gitea WebUI ok, Repos vorhanden