Automated Backup with Rclone and a systemd Timer

There are many options for creating backups. Some solutions have extensive user interfaces or features such as encryption, compression, deduplication and block level incremental backup. A nice open source example of this is Duplicati.

I chose a simple setup with Rclone because it fits my needs well. Rclone can synchronize files from your computer to any of the common cloud storage providers. It can also perform two way synchronization, allowing you to mirror folders across computers. There are many more features listed on the website.

Rclone in action

For storage, Backblaze B2 is reliable and secure while still being cheap. Anything under 10GB is free, and 100GB costs 50 cents per month. B2 has a native ability to keep old versions of files, and the retention policy for old versions is highly configurable.

You can turn on transparent encryption in the bucket settings.

The third piece of the puzzle is a way to run Rclone on a schedule. There are two great options for this, cron jobs and systemd timers. A systemd timer is a more modern solution that can be configured to run periodically based on the time that the last backup job finished.

sudo systemctl status rclone.timer

These services make setup and usage simple while still having all the features I want:

  • Reliability
  • Security
  • Automation
  • Low cost
  • Ability to browse backup files from any phone or computer

Setup Instructions

First, install Rclone. It can be found in most package managers. Then you'll have to configure your remote. If you choose Backblaze B2, create a bucket and generate a new application key to use with Rclone. Add the remote with rclone config.

Next, create a backup script that runs Rclone and specifies the folders you want to back up. I placed my script at /usr/local/bin/rclone-backup.sh

#!/bin/bash

if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
    echo "rclone-backup.sh is already running"
    exit;
fi

rclone sync -v --fast-list --transfers 30 /home/jeremiah/Documents/ b2:backup-bucket-name/Documents/

rclone sync -v --fast-list --transfers 30 --exclude node_modules/ --exclude .git/ /home/jeremiah/Projects/ b2:backup-bucket-name/Projects/
/usr/local/bin/rclone-backup.sh

Give the script executable permissions with chmod +x. Don't forget to test your script when you think it's ready.

Finally, you'll need to set up systemd. Create a systemd service file at /etc/systemd/system/rclone.service

[Unit]
Description=RClone Backup

[Service]
Type=simple
ExecStart=/usr/local/bin/rclone-backup.sh
/etc/systemd/system/rclone.service

Then create a timer at /etc/systemd/system/rclone.timer. Further documentation can be found here.

[Unit]
Description=RClone Backup Timer

[Timer]
Unit=rclone.service
# Run 15 minutes after boot, since the timer must run at least once
# before OnUnitInactiveSec will trigger
OnBootSec=15m
# Run 15 minutes after rclone.service last finished
OnUnitInactiveSec=15m
# Run once when the timer is first started
OnActiveSec=1s

[Install]
WantedBy=timers.target
/etc/systemd/system/rclone.timer

After saving these files, you may need to run:
sudo systemctl daemon-reload

Make the timer start on boot by enabling the timer:
sudo systemctl enable rclone.timer

Start the timer now with:
sudo systemctl start rclone.timer

The backup script should run once and the timer will trigger it again in 15 minutes. You can check the timer status with:
sudo systemctl status rclone.timer

rclone.timer - RClone Backup Timer
 Loaded: loaded (/etc/systemd/system/rclone.timer;
    enabled; vendor preset: disabled)
 Active: active (waiting)
    since Wed 2021-06-16 12:00:24 PDT; 1h 41min ago
 Trigger: Wed 2021-06-16 13:56:10 PDT; 14min left
 Triggers: rclone.service

systemd[1]: Started RClone Backup Timer.

You can also check the status of the service with:
sudo systemctl status rclone.service

rclone.service - RClone Backup
 Loaded: loaded (/etc/systemd/system/rclone.service; static)
 Active: inactive (dead)
    since Wed 2021-06-16 13:41:10 PDT; 6min ago
 TriggeredBy: rclone.timer
 Process: 51857 ExecStart=/usr/local/bin/rclone-backup.sh
    (code=exited, status=0/SUCCESS)
 Main PID: 51857 (code=exited, status=0/SUCCESS)
 CPU: 1.248s

rclone-backup.sh[51917]: INFO: There was nothing to transfer
rclone-backup.sh[51917]: Checks: 476 / 476, 100%
systemd[1]: rclone.service: Deactivated successfully.
systemd[1]: rclone.service: Consumed 1.248s CPU time

If you want to manually run a backup at any time, just start the service manually:
sudo systemctl start rclone.service