Docker & DevOps

Sync VPS backups to Backblaze B2 or Google Drive with rclone

Install rclone on a Linux VPS, connect a Backblaze B2 or Google Drive remote, sync your backup folder off-site on a schedule and confirm the copy with rclone check.

IntermediateLinux server7 min read

To run rclone sync backups to Backblaze B2 you install rclone, add a remote for your bucket, then copy your backup folder off the server on a schedule. This guide covers Ubuntu, Debian, AlmaLinux and Rocky Linux, adds a Google Drive remote as an alternative, and finishes with rclone check so you know the off-site copy really matches.

rclone is a single binary that speaks the APIs of dozens of storage providers. It does not create backups — it moves files you already produced. Pair it with a dump or archive job, then let rclone push the result off the VPS.

Before you start

  • A Linux VPS with root or sudo access. If you are not connected yet, see Connect to your Linux VPS with SSH.
  • A Backblaze B2 account with a bucket created in the web console, plus an application key that has read and write access to that bucket. Note the keyID and applicationKey — the application key is shown once.
  • For Google Drive: a Google account and a browser on another machine, because the OAuth step needs a web login.
  • An existing backup directory, for example /var/backups. If you have not built one yet, start with Automating MySQL backups with mysqldump and cron.
  • The server clock should be correct so cron fires when you expect. See Set the time zone and keep the clock in sync (NTP).

Note: rclone is a transfer tool, not a scheduler. It will happily sync an empty folder over a good copy, so always keep a second copy or enable versioning on the bucket.

Install rclone

The packages in the default repositories are often several releases behind. The official script installs the current build on any of the supported distributions:

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

On AlmaLinux or Rocky you can also use the EPEL package if you prefer to stay inside the package manager:

Bash
sudo dnf install -y epel-release
sudo dnf install -y rclone

Check the version number printed by rclone version. If it looks old, use the install script instead — newer releases fix provider API changes, and B2 and Google Drive both change their endpoints from time to time.

Configure the Backblaze B2 remote

You can do this interactively or in one command. The one-liner is easier to script:

Bash
rclone config create b2backup b2 account 0051a2b3c4d5e6f0000000001 key K005abcdefghijklmnopqrstuvwxyz01234

Replace the account value with your keyID and the key value with your applicationKey. Then list the buckets to confirm the credentials work:

Bash
rclone lsd b2backup:

You should see your bucket name. If you prefer the wizard, run rclone config, choose n for a new remote, name it b2backup, pick b2 from the storage list, paste the two values, leave hard_delete as false, and save.

Lock the config file down, because it holds your keys in plain text:

Bash
chmod 600 ~/.config/rclone/rclone.conf

If you run rclone from a root cron job, the file that matters is /root/.config/rclone/rclone.conf.

Tip: If you want the files encrypted before they leave the server, add a crypt remote on top of the B2 one. rclone obscures the password you pass in: ``bash rclone config create b2crypt crypt remote b2backup:my-bucket/vps-backups filename_encryption standard directory_name_encryption true password $(rclone obscure 'your-long-passphrase') ` Sync to b2crypt:` instead of the raw bucket path. Store the passphrase somewhere safe — without it the data is unreadable.

Configure Google Drive instead

Google Drive works the same way, but the first login needs a browser. On a desktop machine, install rclone and run:

Bash
rclone authorize "drive"

Complete the Google sign-in, then copy the token it prints. On the VPS run rclone config, create a remote named gdrive, choose drive, and paste that token when asked. Non-interactive setups can start with rclone config create gdrive drive scope drive and then rclone config reconnect gdrive: to attach the token.

Google Drive is fine for a few gigabytes of config and database dumps. For large archives, object storage such as B2 is usually cheaper and has no per-file rate limits.

Write the sync script

Create /usr/local/bin/rclone-backup.sh:

Bash
#!/usr/bin/env bash
set -euo pipefail

SOURCE="/var/backups"
REMOTE="b2backup:my-bucket/vps-backups"
LOG="/var/log/rclone-backup.log"

/usr/bin/rclone sync "$SOURCE" "$REMOTE" \
  --b2-hard-delete \
  --transfers 4 \
  --checkers 8 \
  --exclude "*.tmp" \
  --log-file "$LOG" \
  --log-level INFO

Make it executable and run it once by hand:

Bash
sudo chmod +x /usr/local/bin/rclone-backup.sh
sudo /usr/local/bin/rclone-backup.sh
sudo tail -n 30 /var/log/rclone-backup.log

--b2-hard-delete tells B2 to actually remove old versions instead of hiding them, which keeps the bucket from growing forever. Drop that flag if you would rather keep every version.

Warning: rclone sync makes the destination match the source, including deletions. If /var/backups is empty because a dump failed or a disk is not mounted, the remote copy is deleted too. Use rclone copy for an append-only remote, or enable bucket versioning before you rely on sync.

Schedule it with cron

Create /etc/cron.d/rclone-backup:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
30 3 * * * root /usr/local/bin/rclone-backup.sh

Cron runs with a minimal environment, so use absolute paths for both the script and the rclone binary. Add a log rotation rule in /etc/logrotate.d/rclone-backup so the log file does not fill the disk:

/var/log/rclone-backup.log {
    weekly
    rotate 8
    compress
    missingok
    notifempty
}

Check it works

Run these after the first scheduled job:

  1. Compare source and destination file by file:
Bash
rclone check /var/backups b2backup:my-bucket/vps-backups

A clean run reports zero differences. rclone compares hashes where the provider supports them and falls back to size otherwise.

  1. List what is actually stored remotely:
Bash
rclone ls b2backup:my-bucket/vps-backups | head -n 20
  1. Restore a copy to a scratch directory and compare it with the original:
Bash
rclone copy b2backup:my-bucket/vps-backups /tmp/restore-test
diff -r /var/backups /tmp/restore-test
  1. Check the log for the last run:
Bash
tail -n 50 /var/log/rclone-backup.log

A restore test is the only proof that matters. Do it once now, and again whenever you change the script.

Troubleshooting

  • 401 bad_auth_token or 403 from B2 — the keyID or applicationKey is wrong, or the key is scoped to a different bucket. Recreate the application key in the Backblaze console and run rclone config update b2backup account <keyID> key <applicationKey>.
  • didn't find section in config file — the remote name in your script does not match the one in rclone.conf. Run rclone listremotes and compare. Remember that root and your normal user have separate config files.
  • Cron runs but nothing is uploaded — cron cannot find rclone. Use the full path /usr/bin/rclone in the script and set PATH in the cron file as shown above.
  • rateLimitExceeded or userRateLimitExceeded on Google Drive — too many parallel requests. Lower --transfers to 2 and --checkers to 4, and add --drive-chunk-size 32M for large files.
  • Files reappear after deletion on B2 — B2 keeps versions by default, so deleted objects are hidden rather than removed. Add --b2-hard-delete, or clean up old versions with a lifecycle rule in the Backblaze console.
  • corrupted on transfer: sizes differ — a truncated upload, usually from a dropped connection or a full disk. Re-run the job; rclone resumes and re-checks. Confirm free space with df -h.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.