Use rclone for Offsite Server Copies to S3 or Backblaze B2

Create low-cost offsite copies of important server data with a flexible open-source tool that works across many storage providers.

BackupsrcloneOffsite storage
What you learn

How to configure rclone, connect it to S3 or Backblaze B2, copy data safely, and verify that your offsite copy is actually usable.

Best for

Server snapshots, app uploads, database dumps, and any directory that would hurt to lose if the VPS disappeared tomorrow.

Risk to watch

A copy job that has never been tested is not a backup strategy. Verify paths, permissions, and restore assumptions early.

Before you begin

  • A server with data worth keeping offsite.
  • An S3-compatible bucket or a Backblaze B2 bucket.
  • API credentials with access limited to the bucket you intend to use.
  • A clear decision about what to copy, and what should stay out of the backup set.

Local backups protect you from some problems. They do not protect you from total machine loss, provider failure, or a mistake that damages both the server and the local copy. Offsite storage closes that gap. rclone is a strong fit because it is open-source, scriptable, and works with a long list of storage providers without forcing you into one ecosystem.

Why offsite copies are worth the effort

Disaster recovery is mostly about geography and separation. If your only backup lives on the same server or even the same provider volume, it may disappear during the same incident that kills your main data. Sending copies to cheap object storage changes that risk profile dramatically.

Expected outcome: You will have a named rclone remote, a tested copy command, and a repeatable script that can push important files to offsite storage without manual clicking.

Step 1: Install rclone

On Ubuntu, install it from the package repository:

sudo apt update
sudo apt install rclone -y

Check the version:

rclone version

You can also use the official install script from rclone if you need a newer release, but the distro package is often fine for a stable baseline.

Step 2: Configure a storage remote

Launch the interactive configuration wizard:

rclone config

For an S3-compatible target, choose n for a new remote, give it a name like offsite, then choose the s3 storage type. You will be asked for provider details, region, endpoint, access key, and secret key. For Backblaze B2, choose the b2 backend and provide the application key ID and application key.

After setup, test the remote:

rclone lsd offsite:
# or for a specific bucket
rclone lsd offsite:your-bucket-name

If the listing works, authentication is good enough to proceed.

Step 3: Start with copy, not sync

Suppose you want to send app uploads and database dumps offsite:

sudo mkdir -p /var/backups/myapp
sudo tar -czf /var/backups/myapp/uploads-$(date -u +%F).tar.gz /srv/myapp/uploads
pg_dump -U myapp myappdb > /var/backups/myapp/myappdb-$(date -u +%F).sql

Now upload that backup directory with copy:

rclone copy /var/backups/myapp offsite:your-bucket-name/myapp \
  --progress \
  --checksum \
  --transfers 4

copy is safer for beginners than sync because it does not delete files from the destination that are missing locally. Once you fully understand your retention plan, you can decide whether sync or lifecycle rules make sense.

To confirm what is present remotely:

rclone ls offsite:your-bucket-name/myapp | tail

Step 4: Automate the job with a small script

Create a backup script:

nano ~/bin/offsite-backup.sh

Example:

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

STAMP=$(date -u +%F)
BACKUP_DIR=/var/backups/myapp
BUCKET=offsite:your-bucket-name/myapp

mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/uploads-$STAMP.tar.gz" /srv/myapp/uploads
pg_dump -U myapp myappdb > "$BACKUP_DIR/myappdb-$STAMP.sql"
rclone copy "$BACKUP_DIR" "$BUCKET" --checksum
find "$BACKUP_DIR" -type f -mtime +7 -delete

Make it executable and run it:

chmod +x ~/bin/offsite-backup.sh
~/bin/offsite-backup.sh

You can later schedule this with a systemd timer or cron, but the important part is to get one good manual run first.

Expected outcome and verification

A healthy setup means:

  • rclone can authenticate to your remote.
  • The intended backup files appear in the bucket path you expect.
  • You can list or download them without confusion.
  • Your script completes without hidden permission errors.

Useful checks:

rclone about offsite:
rclone ls offsite:your-bucket-name/myapp | tail -n 20
ls -lah /var/backups/myapp
journalctl -n 50 --no-pager | grep -i rclone

The best verification is a small restore test. Download one file to a temporary path and confirm it opens correctly:

mkdir -p /tmp/rclone-restore-test
rclone copy offsite:your-bucket-name/myapp /tmp/rclone-restore-test --max-depth 1
ls -lah /tmp/rclone-restore-test

Troubleshooting common rclone problems

Authentication fails.
Check the access key, secret, region, endpoint, or B2 application key values. One wrong field is enough to make everything look broken.

The upload works manually but fails in a script.
The script may run under a different user with a different rclone.conf. Confirm which account owns the config and whether the script sees the same environment.

Permissions prevent reading the source data.
Your backup user needs access to the directories or dump files you are trying to copy.

You accidentally used sync and removed old remote files.
Stop and check object versioning or bucket lifecycle settings if available. This is why copy is the safer starting point.

Warning: Do not back up live databases by copying their raw data directories unless you already know the engine-specific rules. Use proper dumps or snapshot-aware methods first.

What to do next

Once your offsite copies exist, improve the schedule and observability around them. Continue with How to Schedule Backups and Maintenance with systemd Timers.