SYSTEMS OPERATIONAL
VPS

Automated Off-Site VPS Backups with Cron and Rclone

Getwebup 6 min read

Your VPS is fine right now. That's exactly the problem — nobody sets up real backups on a healthy server, and by the time the disk fails, the provider's data center floods, or a bad rm -rf takes out /var/www, it's too late to start. If your only backup plan is a snapshot from your hosting provider, you have a single point of failure: it lives on the same infrastructure as the server it's protecting. This guide walks through setting up automated, off-site backups on a VPS using cron and rclone — free tools, a script you control, and a copy of your data that survives even if the entire VPS disappears.

Why a Snapshot Alone Isn't a Backup Strategy

A provider snapshot is great for one thing: rolling back a bad kernel update or a botched software install in minutes. But snapshots usually live in the same account, sometimes the same data center, as the VPS itself. If your account gets suspended, the provider has an outage, or you fat-finger a "delete server" button, the snapshot can go with it.

Real disaster recovery needs a copy of your data somewhere else entirely — a different provider, a different region, ideally a different company. That's what this setup gives you: your website files and database dumped, compressed, and pushed to off-site storage every night, without you touching a keyboard.

What You Need Before You Start

  • SSH access to your VPS with a sudo-capable user (not logging in as root directly — see our SSH hardening guide if you haven't set that up yet)
  • An off-site storage destination: Backblaze B2, AWS S3, or even a Google Drive/Dropbox account with enough free space. B2 is the cheapest for pure backup storage.
  • MySQL/MariaDB credentials for the database(s) you want backed up
  • 10–15 minutes of downtime-free setup — none of this touches your live site

Step 1: Install Rclone

Rclone is a single binary that talks to almost every cloud storage provider using one consistent syntax. Install it with the official script:

curl https://rclone.org/install.sh | sudo bash

Confirm it installed correctly:

rclone version

Step 2: Configure a Remote

Run the interactive config wizard:

rclone config

Choose n for a new remote, name it something memorable like b2backup, then pick your provider from the list (Backblaze B2, Amazon S3, Google Drive, etc.) and follow the prompts for your access key and secret. When it's done, test the connection:

rclone lsd b2backup:

If that lists your bucket (or comes back empty with no error), the remote is working.

Step 3: Write the Backup Script

Create a script that dumps your database, archives your site files, and pushes both off-site. Save this as /root/scripts/backup.sh:

#!/bin/bash
set -e

DATE=$(date +%F)
BACKUP_DIR="/root/backups/$DATE"
SITE_DIR="/var/www/html"
DB_NAME="your_database"
DB_USER="your_db_user"
DB_PASS="your_db_password"
REMOTE="b2backup:my-site-backups"

mkdir -p "$BACKUP_DIR"

# Dump the database
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$BACKUP_DIR/db.sql.gz"

# Archive site files
tar -czf "$BACKUP_DIR/files.tar.gz" -C "$SITE_DIR" .

# Push to off-site storage
rclone copy "$BACKUP_DIR" "$REMOTE/$DATE" --transfers=4

# Clean up local copy older than 3 days to save disk space
find /root/backups/* -maxdepth 0 -type d -mtime +3 -exec rm -rf {} \;

# Delete remote backups older than 30 days
rclone delete --min-age 30d "$REMOTE"

Make it executable:

chmod +x /root/scripts/backup.sh

Never hardcode the DB password in a world-readable file. Lock the script down with chmod 700 and keep it under /root, or better, read credentials from a separate .my.cnf file mysqldump picks up automatically.

Step 4: Schedule It with Cron

Open the root crontab:

sudo crontab -e

Add a line to run the backup every night at 2 AM server time:

0 2 * * * /root/scripts/backup.sh >> /var/log/backup.log 2>&1

The >> /var/log/backup.log 2>&1 part matters — without it, cron silently swallows both the output and any errors, and you won't know the backup stopped working until you actually need it.

Cron Schedule Reference

ScheduleCron ExpressionGood For
Nightly0 2 * * *Most WordPress/small business sites
Every 6 hours0 */6 * * *Active WooCommerce stores, frequent content changes
Weekly0 3 * * 0Mostly-static sites, low write volume

Step 5: Actually Test the Restore

This is the step almost everyone skips, and it's the one that matters most. A backup you haven't restored is a guess, not a backup. Pick a quiet moment and run through it once:

  1. Pull a backup down: rclone copy b2backup:my-site-backups/2026-07-14 /tmp/restore-test
  2. Spin up a throwaway database and import the dump: gunzip -c db.sql.gz | mysql -u root -p test_restore_db
  3. Extract the files archive to a scratch directory and spot-check that wp-config.php, uploads, and plugin folders are all there
  4. Time how long the whole process took — that number is your real recovery time, not a guess

Do this test once after setup and then again every few months. Storage providers change APIs, disks fill up, and scripts silently break — you want to find that out on a Tuesday afternoon, not during an actual outage.

Prevention: Keep the Backup Pipeline Honest

  • Alert on failure, not just success. Add a simple check at the end of the script that pings a monitoring service (like a healthchecks.io URL) only if the previous commands succeeded — you'll get notified the moment a night's backup silently fails.
  • Watch disk usage. Local temp copies before the off-site push can fill the disk fast on a busy store. The cleanup line in the script above handles this, but check df -h occasionally.
  • Keep at least one backup outside your Getwebup account entirely. If the goal is surviving a worst-case scenario, the backup can't live in the same blast radius as the thing it protects.
  • Encrypt sensitive dumps. If your database contains customer data, pipe the dump through gpg before it leaves the server, or use rclone's built-in crypt remote.

Snapshots vs. This Setup

These two aren't competing — they cover different failure modes. Keep both:

Provider SnapshotCron + Rclone Off-Site Backup
Speed to restoreMinutes, whole serverSlower, file/database level
Survives account/provider lossNoYes
Good forUndoing a bad update or config changeDisaster recovery, migration, ransomware/hack recovery
GranularityFull disk onlyPick specific files or database tables to restore

Need this done for you instead of scripting it yourself? Getwebup's managed VPS plans include off-site backup configuration as part of onboarding — open a ticket and we'll set the whole pipeline up on your server.

Frequently asked questions

Is a provider snapshot enough, or do I still need off-site backups?

A snapshot is great for quickly undoing a bad update, but it usually lives in the same account and data center as your VPS. If your account is suspended or the provider has an outage, the snapshot can go with it. Off-site backups protect against that scenario, so it's worth running both.

How much does off-site storage like Backblaze B2 cost for a typical site?

For a small to mid-size WordPress or WooCommerce site, database and file backups usually total a few gigabytes per snapshot. Backblaze B2 charges roughly $6 per TB per month, so most sites with a 30-day retention window pay well under a dollar a month.

Why did my cron backup job silently stop running?

The most common cause is the script failing partway through without cron logging it anywhere — always redirect output to a log file with >> /var/log/backup.log 2>&1 in the crontab line. Also check that the mysqldump credentials haven't expired and that the remote storage token hasn't been revoked.

Can I back up multiple databases or multiple sites with one script?

Yes. Loop over an array of database names and site directories inside the script, dumping each to its own dated subfolder before the rclone copy step. Just make sure your remote destination path includes the site name so backups from different sites don't overwrite each other.

How do I restore from one of these backups if my VPS is completely gone?

Spin up a fresh VPS, install rclone, pull the latest backup folder down with rclone copy, then import the SQL dump with mysql and extract the files archive into your web root. Update DNS if the IP changed, and you're back online without needing the original server at all.

#vps #cron #rclone #offsite-backup #backup-automation #disaster-recovery

Keep reading

Chat with Support