This installs root-run backup jobs for Enhance servers. The database job
discovers WordPress sites under /var/www, dumps each local MariaDB database
through socket-auth root access, uploads a plain .tar.gz archive to Backblaze
B2 with rclone's native B2 backend, and removes the local archive only after
remote verification succeeds.
The files job reuses the same rclone credentials, archives each site's
public_html contents, preserves modes, mtimes, ACLs, and xattrs, excludes
common local backup/archive files, uploads to B2, verifies the remote object,
and removes the local archive only after verification succeeds.
Run from this directory:
sudo ./install.shThe installer asks for:
- Backblaze application key ID
- Backblaze application key
- Backblaze bucket name
- Backup folder inside the bucket, for example
database-backups/server-name /var/wwwscan path, temp directory, archive date format, and retention days- Optional systemd timer schedule
Use a restricted Backblaze application key scoped to the backup bucket.
Run from this directory:
sudo ./install-files-backup.shThe files installer reuses /etc/enhance-db-backup/rclone.conf and
/etc/enhance-db-backup/env. By default it changes the database target from:
b2:BUCKET/database-backups/server-name
to:
b2:BUCKET/file-backups/server-name
The default database archive name format is:
testing1_25-5-26_18-00.tar.gz
The default files archive name format is:
testing1_files_25-5-26_18-00.tar.gz
By default file archives use FILES_BACKUP_ARCHIVE_LAYOUT=contents. The archive
contains the contents of public_html, not a top-level public_html directory,
so a website SSH user can extract it from inside the existing public_html.
By default testing1.com becomes testing1. Set this in
/etc/enhance-db-backup/env if you prefer full domains:
BACKUP_NAME_MODE=full-domainWith full-domain, testing1.com becomes testing1.com_25-5-26_18-00.tar.gz.
The installers accept either a preset number or a custom systemd OnCalendar
value.
Database timer presets:
1) Hourly: *-*-* *:00:00
2) Every 2 hours: *-*-* 00/2:00:00
3) Every 3 hours: *-*-* 00/3:00:00
4) Every 6 hours: *-*-* 00/6:00:00
5) Twice daily: *-*-* 02,14:30:00
6) Daily default: *-*-* 02:30:00
Files timer presets:
1) Daily: *-*-* 03:00:00
2) Every 3 days: *-*-01/3 04:00:00
3) Weekly: Sun *-*-* 04:00:00
4) Every 10 days: *-*-01/10 04:00:00
5) Every 14 days: *-*-01/14 04:00:00
6) Monthly: *-*-01 04:00:00
- Database dumps use MariaDB root socket auth, so app database passwords are not copied into backup config.
- Secrets live in
/etc/enhance-db-backup/rclone.conf, owned byroot:root, mode600. - Runtime settings live in
/etc/enhance-db-backup/env, owned byroot:root, mode600. - Temporary files are created under a mode
700working directory. - A
.tar.gzis written into a root-only temporary directory, uploaded with rclone, verified, and deleted only after verification succeeds. - Uploads are retried with
BACKUP_UPLOAD_RETRIES,BACKUP_UPLOAD_RETRY_DELAY, and rclone low-level retries. - If all upload or verification attempts fail, the unverified archive is moved
to
BACKUP_FAILED_DIR, which defaults to/var/tmp/enhance-db-backup/failed. BACKUP_VERIFY_MODE=sizeverifies that the remote object exists and matches the local archive size.BACKUP_VERIFY_MODE=deepdownloads the archive and validates the tar/gzip stream, but doubles transfer for each backup.BACKUP_LOCK_MODE=autouses non-blocking--single-transactiondumps for all-InnoDB databases and switches to--lock-tablesonly when a database has non-transactional tables.- Remote retention uses
BACKUP_RETENTION_DAYS;0disables automatic remote deletion. - File backups use
FILES_BACKUP_RCLONE_TARGET,FILES_BACKUP_RETENTION_DAYS,FILES_BACKUP_VERIFY_MODE, andFILES_BACKUP_ARCHIVE_LAYOUT. - For customer self-restore, keep the existing
public_htmldirectory in place and extract the archive inside it as the website SSH user. - For root-level restores from the parent site directory, set
FILES_BACKUP_ARCHIVE_LAYOUT=public_html.
Dry-run discovery:
sudo enhance-db-backup --dry-runRun a backup:
sudo enhance-db-backupList remote archives:
sudo bash -c 'set -a; . /etc/enhance-db-backup/env; set +a; rclone --config "$BACKUP_RCLONE_CONFIG" lsf "$BACKUP_RCLONE_TARGET"'Systemd timer:
systemctl status enhance-db-backup.timer
journalctl -u enhance-db-backup.serviceDry-run discovery:
sudo enhance-files-backup --dry-runRun a backup:
sudo enhance-files-backupList remote file archives:
sudo bash -c 'set -a; . /etc/enhance-db-backup/env; set +a; rclone --config "$BACKUP_RCLONE_CONFIG" lsf "$FILES_BACKUP_RCLONE_TARGET"'Systemd timer:
systemctl status enhance-files-backup.timer
journalctl -u enhance-files-backup.serviceIf file backups upload only the first few sites and then stop, check for a systemd timeout, live files changing during tar, or local plugin backup files:
journalctl -u enhance-files-backup.service --since todayFix an already-installed server:
sudo sed -i '/^ExecStart=/a TimeoutStartSec=0' /etc/systemd/system/enhance-files-backup.service
sudo systemctl daemon-reload
sudo systemctl restart enhance-files-backup.timerIf logs show file changed as we read it or local .wpress archives are being
included, update the installed runner from the latest repo version:
sudo install -o root -g root -m 0755 enhance-files-backup.sh /usr/local/sbin/enhance-files-backup
sudo bash -n /usr/local/sbin/enhance-files-backupNew installs include these settings automatically.
Use db-restore.md for database restores and files-restore.md for
owner-preserving WordPress file restores.