9.3 KiB
app-backup (Rocky Linux 10) – Split-Backups für WordPress, Nextcloud, Gitea + DBs (OneDrive/rclone)
Dieses Repo enthält ein Backup- und Restore-Setup für typische Self-Hosted-Apps auf Rocky Linux 10:
- 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
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.
✅ 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 Excludedata/)..._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 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_DIRwirddata/explizit ausgeschlossen (rsync --exclude data/). - Danach wird
NC_DATA_DIRals 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, wennNC_DIRgenauWP_DIR/nextcloudist.
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:
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
2) DB Credential Files anlegen
Für WordPress / Nextcloud / Gitea je eine .cnf.
Beispiele:
/etc/app-backup/db-wordpress.cnf/etc/app-backup/db-nextcloud.cnf/etc/app-backup/db-gitea.cnf
Inhalt:
[client]
user=backup
password=DEIN_PASSWORT
host=localhost
Rechte:
sudo chown root:root /etc/app-backup/db-*.cnf
sudo chmod 600 /etc/app-backup/db-*.cnf
3) MariaDB Backup-User (Minimal-Rechte)
Pro DB (z.B. gitea):
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):
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 configals root durchführen und Remote anlegen.
Option B – root nutzt Config von johannes
- im Script/Service
RCLONE_CONFIG=/home/johannes/.config/rclone/rclone.confsetzen - oder in systemd Unit
Environment=RCLONE_CONFIG=...
⚙️ Konfiguration: app-backup.conf (wichtige Stellen)
OneDrive Remote Base
RCLONE_REMOTE_BASE="OneDrive:Sicherung/JRITServerBackups/$(hostname -s)"
Das Skript legt pro Run einen Unterordner an:
remote_run="${RCLONE_REMOTE_BASE}/appbackup_<timestamp>"
WordPress / Nextcloud Layout (wichtig!)
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/htmlohnenextcloud/ - Nextcloud Code =
/var/www/html/nextcloudohnedata/ - Nextcloud Data =
/var/www/html/nextcloud/dataseparat
Gitea (native + MariaDB)
Aus deinem systemd/app.ini:
WorkingDirectory=/var/lib/giteaAPP_DATA_PATH=/var/lib/gitea/data- config:
/etc/gitea/app.ini
Daher:
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
sudo /usr/local/sbin/app-backup.sh
Erwartetes Verhalten:
- Lock
/run/app-backup.lockverhindert Parallelruns - optional stoppt es Gitea kurz (konsistenter Snapshot)
- Dumps: wordpress / nextcloud / gitea
- rsync in staging
- mehrere
.tar.zstwerden erzeugt - Upload pro Datei nach OneDrive (falls
ENABLE_UPLOAD=true) - Remote retention (best effort)
- 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:
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:
sudo /usr/local/sbin/app-restore.sh --local-run /var/backups/app-backup/archives/<run-folder>
Dry-Run
sudo /usr/local/sbin/app-restore.sh --remote-run appbackup_... --dry-run
Nur Files / nur DB
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_DIRzurück synchronisiert /etc/giteawird 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 nutztonedrive:→ case-sensitive. - Backup läuft als
root, aber rclone config ist nur beijohannes.
Prüfen:
sudo rclone listremotes
sudo -u johannes rclone listremotes
Fix:
- Entweder rclone remote auch für root konfigurieren,
- oder
RCLONE_CONFIGauf johannes’ Config zeigen lassen.
2) Nextcloud Data doppelt oder fehlt
Stellen prüfen:
NC_DIRkorrekt?NC_DATA_DIRkorrekt?- Das Skript excludet
data/bei Nextcloud Code. Data wird separat gesichert.
3) Große Uploads brechen ab
Setze z.B.:
RCLONE_TRANSFERS=1RCLONE_CHECKERS=2RCLONE_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:
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
[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
[Unit]
Description=Run app-backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Aktivieren:
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