One aspect of having a website is to make sure there are backup if and when something goes terribly wrong. Backing up a traditional web application (fe. a WordPress installation) requires backing up both the files and the database (usually a MySQL/MariaDB one).

Restic is a nifty backup tool1 that supports many different places to store the files, one among them Backblaze’s B2 service. B2 has a generous free plan and it’s also one of the most cost-effective solutions for cloud based backups. Restic supports also Amazon’s S3, Microsoft’s Azure and Google’s Cloud Storage among other options. Just change the relevant environment variables and repostiory names to match up with your backup target.

To begin, first create a bucket at B2 (or other service) and write down your Account ID and Application Key so Restic can access the cloud storage service.

Initializing the repository

export B2_ACCOUNT_ID=YOUR_ACCOUNT_ID
export B2_ACCOUNT_KEY=YOUR_APPLICATION_KEY
restic -r b2:YOUR_B2_BUCKET_NAME init

These commands will create the backup repository to the root of the bucket, you can alternatively set a path with restic -r b2:YOUR_B2_BUCKET_NAME:path/to/repo init. The repository initialization will ask you for a password that will be needed every time you want to access the repository with Restic, below this password is defined in the environment variable RESTIC_PASSWORD.

The account crendentials could be given as parameters to Restic, but in case yo u want to explore restic’s commands it saves some typing to have them set as environment variables.

Next up, create the below simple shell script to do both backups and prune the backups. This will be script that you schedule later to do your backups.

# backup-script.sh
export B2_ACCOUNT_ID=YOUR_ACCOUNT_ID
export B2_ACCOUNT_KEY=YOUR_APPLICATION_KEY
export RESTIC_REPOSITORY=b2:YOUR_B2_BUCKET_NAME
export RESTIC_PASSWORD=BACKUP_REPO_PASSWORD

restic backup /path/to/website
mysqldump --databases website_database -u database_user | restic backup --stdin --stdin-filename database_dump.sql
restic forget --prune --keep-daily 30 --keep-weekly 52

The first export lines set up the enviroment variables for the commands. The first command backs up the files located at /path/to/website. The second one runs mysqldump2 and pipes the output straight to restic as database_dump.sql. The third one will prune Restic’s backup repository so that it will keep last 30 daily backups and last 52 weekly backups. You can choose your own snapshot retention policy by using the various parameters available for forget.

You might want to make sure that the script is both executable by you and not readable by other users on the system by running chmod 700 backup-script.sh.

Due to security reasons3 it is not recommended to use -pdatabase_password in a mysqldump command but instead to store the password in the configuration file ~/.my.cnf:

# ~/.my.cnf
[mysqldump]
password=database_password

Remember to set the configuration file’s permissions so that only the backup user (ie. your account) can read the file with chmod 600 .my.cnf.

You can now do test drive by running ./backup-script.sh and you should see restic backuping both your files and database to Backblaze.

Scheduling the backup task with Crontab

The following line in crontab -e will run the backup script every day at midnight. By default, any output form cron task will be sent as an email so the output will be redirected to a log file. In the case the script fails, the 2>&1 also redirects standard error channel to standard output, ie. to the log file.

0 0 * * * /path/to/backup-script.sh > /path/to/backup-script.log 2>&1

Congratulations, you should now have a simple and effective backups set in place. Let’s hope you never have to use them but you can now stress about one thing less.