Harden backup integrity, implement verified restore and safe upgrades
This commit is contained in:
1 parent
099688ea48
commit
4d58fc7b66
22 files changed
+1928
-1106
No files matched your search
@@ -1,340 +1,147 @@
|
||||
# app-backup (Rocky Linux 10) – Split-Backups für WordPress, Nextcloud, Gitea + DBs (OneDrive/rclone)
|
||||
# app-backup – geprüfte Sicherungen für den JR IT Server
|
||||
|
||||
Dieses Repo enthält ein **Backup- und Restore-Setup** für typische Self-Hosted-Apps auf Rocky Linux 10:
|
||||
Sichert WordPress, Nextcloud, native Gitea-Installationen mit MariaDB, Maildaten und zusätzliche Verzeichnisse. Jede Komponente erhält ein eigenes Archiv. Uploads gehen ausschließlich über ein **rclone-Crypt-Remote**; anschließend wird der gesamte Inhalt durch dieses Remote zurückgelesen und verglichen.
|
||||
|
||||
- **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**
|
||||
Die vollständige Analyse, Architektur, Konfiguration, Betriebsanleitung und verbleibenden Grenzen stehen in [Dokumentation.md](Dokumentation.md).
|
||||
|
||||
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.
|
||||
## Wesentliche Änderungen
|
||||
|
||||
---
|
||||
- Funktionierender Restore mit Prüflauf, Entpackmodus, Komponentenauswahl und ausdrücklichem `--apply --yes`.
|
||||
- Fehler bei Dump, rsync, Kompression und Rückleseprüfung brechen den Lauf ab.
|
||||
- Wartungsmodus und Dienststopps umfassen Datenbankdump **und** Dateikopie. Danach endet die Ausfallzeit; Kompression und Upload laufen aus dem Staging.
|
||||
- Vollständige Sicherungssätze mit SHA-256-Manifest, Archivprüfung und zuletzt hochgeladenem `COMPLETE`-Marker.
|
||||
- Retention löscht nur vollständige neue Sicherungssätze und behält mindestens `RETENTION_KEEP_LAST` Läufe. Alte Sicherungen werden nicht automatisch gelöscht.
|
||||
- Private Arbeitsverzeichnisse, gemeinsame Sperre für Backup/Restore/Update und Wiederanlaufhinweise nach Abbrüchen.
|
||||
- Installer erhält die Serverkonfiguration und den Zeitplan und erstellt ein Rollback-Paket.
|
||||
|
||||
## ✅ Ziele / Designentscheidungen
|
||||
## Bestehende Installation aktualisieren
|
||||
|
||||
### 1) Split statt „dickes Archiv“
|
||||
Es werden pro Lauf mehrere Archive erzeugt (zstd oder gzip):
|
||||
**Vor dem ersten Lauf:** Für ein konsistentes Backup werden nun standardmäßig `httpd`, `php-fpm`, `postfix` und `dovecot` während der Kopie angehalten, soweit die zugehörigen Anwendungen aktiviert sind und die Dienste laufen. Fehlende Einstellungen in alten Konfigurationen erhalten diese neuen Defaults. Zusätzliche Cronjobs/Worker müssen in `QUIESCE_SERVICES` erfasst oder extern angehalten werden. Zeitfenster und Datenumfang vorher prüfen.
|
||||
|
||||
- `..._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)
|
||||
Die bisherigen echten `*.cnf`-Dateien wurden aus dem aktuellen Repository entfernt. **Vor `git pull` auch mögliche Zugangsdaten im Server-Checkout sichern.** Historische Commits können die alten Werte weiterhin enthalten; betroffene Datenbankpasswörter wechseln. Die Dateien unter `/etc/app-backup` werden vom Installer nicht überschrieben.
|
||||
|
||||
Vorteile:
|
||||
- Upload stabiler bei **12–18 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>/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Installation / Setup
|
||||
|
||||
### 1) Skripte installieren
|
||||
Beispiel:
|
||||
```bash
|
||||
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
|
||||
# Auf dem Server, im vorhandenen Checkout:
|
||||
cd /pfad/zum/app-backup
|
||||
sudo systemctl stop app-backup.timer
|
||||
systemctl is-active app-backup.service
|
||||
# Falls aktiv: den laufenden Job zuerst regulär fertig werden lassen.
|
||||
|
||||
# Einmalige geschützte Sicherung, bevor git pull alte Dateien aus dem Checkout entfernt:
|
||||
sudo install -d -m 700 /var/backups/app-backup-before-v2
|
||||
sudo cp -a /etc/app-backup /var/backups/app-backup-before-v2/etc-app-backup
|
||||
sudo cp -a etc/app-backup /var/backups/app-backup-before-v2/checkout-app-backup
|
||||
|
||||
git status --short
|
||||
# Lokale Anpassungen vorher sichern/auflösen; keinen Reset erzwingen.
|
||||
git pull --ff-only
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
### 2) DB Credential Files anlegen
|
||||
Für WordPress / Nextcloud / Gitea je eine `.cnf`.
|
||||
Der Installer nennt anschließend einen Ordner wie `/var/backups/app-backup-update-XXXXXXXX` mit alten Paketdateien und `rollback.sh`. Weil der Timer zuvor gestoppt wurde, bleibt er beim Update gestoppt. Eine sonst aktive Timer-Instanz wird vom Installer nach erfolgreichem Update wieder aktiviert; deshalb ist der vorherige Stopp für die Migration wichtig.
|
||||
|
||||
Beispiele:
|
||||
- `/etc/app-backup/db-wordpress.cnf`
|
||||
- `/etc/app-backup/db-nextcloud.cnf`
|
||||
- `/etc/app-backup/db-gitea.cnf`
|
||||
|
||||
Inhalt:
|
||||
```ini
|
||||
[client]
|
||||
user=backup
|
||||
password=DEIN_PASSWORT
|
||||
host=localhost
|
||||
```
|
||||
|
||||
Rechte:
|
||||
```bash
|
||||
sudo chown root:root /etc/app-backup/db-*.cnf
|
||||
sudo chmod 600 /etc/app-backup/db-*.cnf
|
||||
# Neue Optionen mit der bestehenden Konfiguration abgleichen (Datei enthält keine DB-Passwörter):
|
||||
sudo diff -u /etc/app-backup/app-backup.conf /etc/app-backup/app-backup.conf.dist
|
||||
sudoedit /etc/app-backup/app-backup.conf
|
||||
|
||||
# Vorhandene Dateinamen aus WP_DB_CNF / NC_DB_CNF / GITEA_DB_CNF verwenden:
|
||||
sudo chown root:root /etc/app-backup/*.cnf
|
||||
sudo chmod 600 /etc/app-backup/*.cnf
|
||||
sudo chmod 600 /etc/app-backup/app-backup.conf
|
||||
# Den tatsächlich konfigurierten rclone-Dateipfad verwenden:
|
||||
sudo chown root:root /root/.config/rclone/rclone.conf
|
||||
sudo chmod 600 /root/.config/rclone/rclone.conf
|
||||
|
||||
sudo /usr/local/sbin/app-backup.sh --check
|
||||
# Im vereinbarten Wartungsfenster den ersten vollständigen Lauf ausführen:
|
||||
sudo systemctl start app-backup.service
|
||||
sudo journalctl -u app-backup.service -n 100 --no-pager
|
||||
sudo cat /var/backups/app-backup/last-backup.json
|
||||
```
|
||||
|
||||
### 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;
|
||||
```
|
||||
`--check` prüft Werkzeuge, Quellpfade, Dateirechte, DB-Verbindungen, Speicherreserve und Crypt-Zugriff. Es stoppt keine Anwendungen und führt weder Backup noch Upload aus. Es ersetzt keinen vollständigen Probelauf.
|
||||
|
||||
Optional: denselben User für wordpress/nextcloud verwenden, dann jeweils `GRANT ... ON wordpress.*` etc.
|
||||
In der Konfiguration insbesondere ergänzen/prüfen:
|
||||
|
||||
### 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
|
||||
RCLONE_CONFIG="/root/.config/rclone/rclone.conf"
|
||||
RCLONE_REMOTE_BASE="OneDriveCrypt:gemini" # vorhandenes Crypt-Ziel beibehalten!
|
||||
RETENTION_KEEP_LAST=3
|
||||
ENABLE_REMOTE_RETENTION="false" # während der Migration zunächst aus
|
||||
MAIL_BACKUP_MODE="stop"
|
||||
# Tatsächliche Timer-/Service-Namen einsetzen; Timer vor seinem Service nennen:
|
||||
QUIESCE_SERVICES=()
|
||||
# Gitea war in der bisherigen mitgelieferten Konfiguration NICHT aktiviert:
|
||||
# ENABLE_GITEA="true" nach Prüfung aller Gitea-Pfade und DB-Einstellungen setzen.
|
||||
```
|
||||
|
||||
⚠️ Wichtig: Wenn das Backup als `root` läuft, muss `root` auch Zugriff auf die rclone config haben.
|
||||
Typisch sind zwei Wege:
|
||||
Den neuen Laufnamen aus Log oder `last-backup.json` übernehmen:
|
||||
|
||||
**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)"
|
||||
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_DATUM_UHRZEIT_ID --verify-only
|
||||
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_DATUM_UHRZEIT_ID --extract-only
|
||||
```
|
||||
|
||||
Das Skript legt pro Run einen Unterordner an:
|
||||
`DATUM_UHRZEIT_ID` ist ein Platzhalter, z. B. `2026-09-10_02-30-00_a1b2c3d4`. Der Entpackmodus nennt seinen geschützten Ergebnisordner. Nach Prüfung der Dateien und einer erfolgreichen Wiederherstellungsprobe auf einem Testsystem den Zeitplan einschalten:
|
||||
|
||||
```bash
|
||||
remote_run="${RCLONE_REMOTE_BASE}/appbackup_<timestamp>"
|
||||
sudo systemctl enable --now app-backup.timer
|
||||
systemctl list-timers app-backup.timer
|
||||
```
|
||||
|
||||
### WordPress / Nextcloud Layout (wichtig!)
|
||||
**Rückweg bei einem Paketproblem:** Timer stoppen, aktiven Job fertig werden lassen und das vom Installer erzeugte Skript ausführen:
|
||||
|
||||
```bash
|
||||
WP_DIR="/var/www/html"
|
||||
NC_DIR="/var/www/html/nextcloud"
|
||||
NC_DATA_DIR="/var/www/html/nextcloud/data"
|
||||
sudo /var/backups/app-backup-update-XXXXXXXX/rollback.sh
|
||||
```
|
||||
|
||||
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
|
||||
Das stellt die ersetzten Paketdateien wieder her. Konfigurationsänderungen und bereits zurückgeschriebene Anwendungsdaten werden dadurch nicht rückgängig gemacht. Der Timer bleibt bis zur manuellen Prüfung gestoppt. Der alte Stand enthält die im Review beschriebenen Mängel.
|
||||
|
||||
### Gitea (native + MariaDB)
|
||||
Aus deinem systemd/app.ini:
|
||||
- `WorkingDirectory=/var/lib/gitea`
|
||||
- `APP_DATA_PATH=/var/lib/gitea/data`
|
||||
- config: `/etc/gitea/app.ini`
|
||||
## Neuinstallation
|
||||
|
||||
Benötigt Linux mit systemd, Bash ≥ 4.4, Python ≥ 3.9, GNU tar/coreutils, rsync mit ACL/xattr-Unterstützung, zstd bzw. gzip, sudo, PHP/occ, MariaDB-Clients und rclone. Details und Rechte siehe [Dokumentation](Dokumentation.md#voraussetzungen-und-konfiguration).
|
||||
|
||||
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"
|
||||
git clone https://gitea.jr-it-services.de/johannes/app-backup.git
|
||||
cd app-backup
|
||||
sudo ./install.sh
|
||||
sudoedit /etc/app-backup/app-backup.conf
|
||||
# DB-Dateien aus *.cnf.example erstellen; root:root und chmod 600 setzen.
|
||||
# rclone Crypt als root konfigurieren, Schlüssel getrennt sicher verwahren.
|
||||
sudo /usr/local/sbin/app-backup.sh --check
|
||||
```
|
||||
|
||||
---
|
||||
Der Installer aktiviert bei einer Neuinstallation den Timer standardmäßig **erst auf ausdrückliche Anforderung**. Nach Backup- und Restore-Probe: `sudo systemctl enable --now app-backup.timer`.
|
||||
|
||||
## ▶️ Backup ausführen
|
||||
## Backup und Restore
|
||||
|
||||
```bash
|
||||
sudo /usr/local/sbin/app-backup.sh
|
||||
|
||||
# Standard ist ein geprüfter Plan, ohne Änderungen an den Anwendungen:
|
||||
sudo /usr/local/sbin/app-restore.sh --local-run /var/backups/app-backup/archives/LAUFNAME
|
||||
|
||||
# Ausführung überschreibt ausgewählte Dateien und Datenbankobjekte:
|
||||
sudo /usr/local/sbin/app-restore.sh --config /etc/app-backup/restore.conf \
|
||||
--local-run /var/backups/app-backup/archives/LAUFNAME --apply --yes
|
||||
|
||||
# Nur WordPress-Dateien; Konfiguration definiert die Zielpfade:
|
||||
sudo /usr/local/sbin/app-restore.sh --local-run /var/backups/app-backup/archives/LAUFNAME \
|
||||
--components wordpress --no-db --apply --yes
|
||||
|
||||
# Alte Split-Archive ohne Manifest: nur kontrolliert entpacken, manuell prüfen/importieren:
|
||||
sudo /usr/local/sbin/app-restore.sh --local-run /pfad/zu/einem/alten/lauf \
|
||||
--legacy-unverified --extract-only
|
||||
```
|
||||
|
||||
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
|
||||
Ein echter Restore benötigt passende Zielverzeichnisse, Anwendungsstände und Datenbanken sowie einen DB-Account mit Wiederherstellungsrechten. `--yes` ist keine automatische Datenrettung bei Fehlern; bei einem Teilfehler bleiben angehaltene Dienste für die manuelle Prüfung stehen.
|
||||
|
||||
---
|
||||
## Tests
|
||||
|
||||
## ♻️ 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
|
||||
docker build -t app-backup-test -f tests/Dockerfile .
|
||||
docker run --rm --network none -v "$PWD:/src:ro" app-backup-test
|
||||
```
|
||||
|
||||
### 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 -u johannes rclone listremotes
|
||||
```
|
||||
|
||||
Fix:
|
||||
- Entweder rclone remote auch für root konfigurieren,
|
||||
- oder `RCLONE_CONFIG` auf johannes’ Config zeigen lassen.
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 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
|
||||
ShellCheck, echte MariaDB-Dumps/Imports, gzip/zstd, rsync, lokale Crypt-Uploads und Remote-Restore sowie Fehlerfälle laufen im Container. systemd und Nextcloud-occ sind simuliert. Eine echte Rocky-/Nextcloud-/Gitea-/OneDrive-Wiederherstellungsprobe bleibt Teil der Serverabnahme.
|
||||
Reference in new issue
Block a user