← Back to notes

VPS Backups to Wasabi

VPS Backups to Wasabi.md

VPS Backups to Wasabi

The Script

mkdir -p /root/scripts /root/backups /var/log/vps-backups

cat << 'EOF' > /root/scripts/vps-backup.sh
#!/bin/bash
set -euo pipefail

REMOTE="rondoyle-wasabi"
BUCKET="rondoyle-vps-backups"

REMOTE_ROOT="${REMOTE}:${BUCKET}"
REMOTE_FILES_PATH="${REMOTE_ROOT}/files"
REMOTE_DB_PATH="${REMOTE_ROOT}/mysql"

LOG_FILE="/var/log/vps-backups/vps-backup.log"

DATESTAMP="$(date +%F-%H-%M-%S)"
HOSTNAME_SHORT="$(hostname -s)"

FILES_NAME="${HOSTNAME_SHORT}-files-${DATESTAMP}.tar.gz"
DB_NAME="${HOSTNAME_SHORT}-mysql-${DATESTAMP}.sql.gz"

exec >> "${LOG_FILE}" 2>&1

echo "=================================================="
echo "Backup started: $(date)"
echo "Host: ${HOSTNAME_SHORT}"

command -v mysqldump >/dev/null 2>&1 || { echo "ERROR: mysqldump not found"; exit 1; }
command -v rclone >/dev/null 2>&1 || { echo "ERROR: rclone not found"; exit 1; }
command -v tar >/dev/null 2>&1 || { echo "ERROR: tar not found"; exit 1; }
command -v gzip >/dev/null 2>&1 || { echo "ERROR: gzip not found"; exit 1; }

echo "Ensuring remote paths exist..."
rclone mkdir "${REMOTE_FILES_PATH}"
rclone mkdir "${REMOTE_DB_PATH}"

echo "Streaming MySQL dump to Wasabi..."
mysqldump --single-transaction --quick --all-databases \
  | gzip \
  | rclone rcat "${REMOTE_DB_PATH}/${DB_NAME}"

echo "Verifying MySQL upload..."
rclone ls "${REMOTE_DB_PATH}" | grep -F "${DB_NAME}" >/dev/null

echo "Streaming files archive to Wasabi..."
tar -czpf - \
  /home \
  /etc \
  /var/spool/cron \
  /var/cpanel \
  2>/dev/null \
  | rclone rcat "${REMOTE_FILES_PATH}/${FILES_NAME}"

echo "Verifying files upload..."
rclone ls "${REMOTE_FILES_PATH}" | grep -F "${FILES_NAME}" >/dev/null

echo "Applying retention policy (keep 21 days)..."
rclone delete "${REMOTE_FILES_PATH}" --min-age 21d
rclone delete "${REMOTE_DB_PATH}" --min-age 21d

echo "Backup complete: $(date)"
EOF

chmod 700 /root/scripts/vps-backup.sh

Run Backup Manually (from root)

/root/scripts/vps-backup.sh

Confirm Backup

rclone ls rondoyle-wasabi:rondoyle-vps-backups/files
rclone ls rondoyle-wasabi:rondoyle-vps-backups/mysql
tail -n 50 /var/log/vps-backups/vps-backup.log

Setup CRON

crontab -e

Note: That screen is Vim, not nano. Press i to edit. Press ESC to Save. Press :wq to exit.

For a nightly backup at 2:30 AM

30 2 * * * /root/scripts/vps-backup.sh