Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Enhance Website Backups

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.

Install

One command sets up both the database and files backups. Straight from GitHub:

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/wnstify/backup-enhance/main/install.sh)"

This fetches both runners and the shared library into a temp directory and walks you through setup. Prompts read from the terminal, so the command stays interactive. Or, from a clone of this repo:

sudo ./install.sh

The installer asks for:

  • Backblaze application key ID and application key
  • Backblaze bucket name
  • Database backup folder inside the bucket, for example database-backups/server-name
  • /var/www scan path, temp directory, archive date format, name mode, and database retention days
  • File backup rclone target (defaults to the database target with database-backups swapped for file-backups), files retention, verify mode, and archive layout
  • Optional systemd timer schedules for the database and files jobs

Use a restricted Backblaze application key scoped to the backup bucket.

Re-running the installer upgrades an existing server in place: it detects the stored B2 key and offers to keep it (so you do not re-enter credentials), and prefills every prompt from the current /etc/enhance-db-backup/env. The default files target is derived from the database target:

b2:BUCKET/database-backups/server-name   ->   b2:BUCKET/file-backups/server-name

Backup Naming

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-domain

With full-domain, testing1.com becomes testing1.com_25-5-26_18-00.tar.gz.

Timer Presets

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

Security Model

  • 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 by root:root, mode 600.
  • Runtime settings live in /etc/enhance-db-backup/env, owned by root:root, mode 600.
  • Temporary files are created under a mode 700 working directory.
  • A .tar.gz is 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=size verifies that the remote object exists and matches the local archive size. BACKUP_VERIFY_MODE=deep downloads the archive and validates the tar/gzip stream, but doubles transfer for each backup.
  • BACKUP_LOCK_MODE=auto uses non-blocking --single-transaction dumps for all-InnoDB databases and switches to --lock-tables only when a database has non-transactional tables.
  • Remote retention uses BACKUP_RETENTION_DAYS; 0 disables automatic remote deletion.
  • The [b2] remote sets hard_delete = true and the prune passes --b2-hard-delete, so retention permanently removes old object versions. On a versioned bucket without this, rclone delete only writes a hide-marker and every "deleted" archive keeps billing forever.
  • File backups use FILES_BACKUP_RCLONE_TARGET, FILES_BACKUP_RETENTION_DAYS, FILES_BACKUP_VERIFY_MODE, and FILES_BACKUP_ARCHIVE_LAYOUT.
  • For customer self-restore, keep the existing public_html directory 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.

Manual Database Commands

Dry-run discovery:

sudo enhance-db-backup --dry-run

Run a backup:

sudo enhance-db-backup

List 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.service

Manual File Commands

Dry-run discovery:

sudo enhance-files-backup --dry-run

Run a backup:

sudo enhance-files-backup

List 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.service

Existing Server Fixes

If 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 today

Fix 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.timer

If logs show file changed as we read it or local .wpress archives are being included, update the installed runners from the latest repo version by re-running the installer. It inlines the shared library into each runner, syntax-checks the assembled result, and reinstalls it:

sudo ./install.sh

Re-running is a safe in-place upgrade: it keeps your stored B2 key and prefills every prompt from the current /etc/enhance-db-backup/env. Installing a runner by hand no longer works, because each runner sources enhance-backup-lib.sh, which the installer inlines; only install.sh produces a standalone runner.

New installs include these settings automatically.

On a server installed before hard-delete, add hard_delete = true under [b2] in /etc/enhance-db-backup/rclone.conf, reinstall the runners from this repo, then reap the hidden version backlog once (live 7-day window untouched):

sudo bash -c 'set -a; . /etc/enhance-db-backup/env; set +a; \
  rclone --config "$BACKUP_RCLONE_CONFIG" cleanup "$BACKUP_RCLONE_TARGET"; \
  rclone --config "$BACKUP_RCLONE_CONFIG" cleanup "$FILES_BACKUP_RCLONE_TARGET"'

Restore

Use db-restore.md for database restores and files-restore.md for owner-preserving WordPress file restores.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages