Backing Up Nextcloud with Backblaze B2

Tags: technical backup selfhosting

Recently I’ve started hosting a lot of my own data using Nextcloud. It is an excellent alternative to likes of Dropbox & Google Drive and provides a lot of good features out of the box, e.g. a really great user interface, Calendar and Contacts, RSS reader, etc. along with native apps for all the desktop and mobile OSes.

This is a good alternative to other cloud providers because overall it’s pretty cheap when there’s a need to scale up, although I had to research and find relatively cheap infrastructure providers which provided the features that I needed, without providing a lot of enterprisey features which a single user like me won’t need (r/selfhosted really helped me with finding the alternatives). In the end, I started with Hetzner for hosting the server and Backblaze B2 for cheap backups. The combination has been working really well for last 4 months or so, without any downtime.

As an aside, Hetzner also provides Nextcloud boxes which are pretty cheap but since I use my VPS for some other stuff I didn’t pick that option.

In this setup, I assume that you already have a Nextcloud server running on a VPS. I touch upon the details of my setup, but won’t go in-depth. Essentially, I cover how to provision a volume, use that to store NC data, encrypt and back that up to Backblaze B2 using rclone (and cron).

Setting Up Hetzner (Optional)

First and foremost, one needs to create an account on Hetzner. The procedure over there is quite different as they require copy of the passport to be sent as part of their installation. Someone from their team checks it and activates your account. They give the option of encrypting the passport copy with their gpg before sending them the passport. This helps in countering the fake accounts that crop up to use their inexpensive VPS solutions.

Changes to Nextcloud to use an External Volume

Once a VPS is procured, take it for a spin and install Nextcloud. As I mentioned, in my setup, I’ve created a volume to store all the nextcloud data.

There are 2 changes that I’ve done in my setup:

  • Since apache runs as www-data user, this folder needs to give the permissions to this user. I’ve also added a group called cloud which has all the users who can read through the data of multiple other services running on my machine.

  • The config of nextcloud by default uses datadirectory as /var/www/nextcloud/data and I’ve changed it to /mnt/volume-nbg1-1/nextcloud/data. The file should be available in the nextcloud root directory in the config folder.

Get a Backblaze B2 account.

Unlike Hetzner, these guys just need your email address and credit card details. Create an account over there, and then create a bucket. I generally append a guid to my bucket name as these have to be globally unique.

Once the bucket is created, create an Application key using the App Keys menu on the left. Note down the keyId and applicationKey.

Setup A User To Backup Data

As mentioned before, and to keep a separation of different users, I created a user which has read access to services running on my machine. Let’s call that user syncuser. This user will be part of the cloud group and therefore will read access to the nextcloud data directory. Essentially, you’d need to run these commands.

useradd syncuser
usermod -aG cloud syncuser

Setup rclone

rclone is an excellent sync utility with backends for (almost?) all the cloud providers in existence. It is ultra fast and super simple to set up.

This step of setting rclone contains 2 substeps:

  1. Setup rclone for Backblaze B2

    This configuration uses the keyid and applicationKey which we saved while creating app keys for B2. Let’s assume that you named this backend b2 during the rclone configuration, then go ahead and sync a couple of files using the following commands:

    mkdir -p temp/{dir1,dir2}
    touch temp/{dir1,dir2}/{file1,file2}
    rclone copy temp b2:bucketname
    rclone ls b2:bucketname

    This should list out dir1 and dir2.

    This backend doesn’t really encrypts the data. We need to setup a crypt backend for encryption to actually work.

  2. Setup crypt for the backend

    While doing the configuration for crypt, the setup asks for quite a few things. Here’s a list of values you might use, based on the steps we’ve taken till now:

    • New remote -> name -> b2-crypt

    • Type of storage -> crypt

    • Remote to encrypt/decrypt -> b2-crypt:bucketname

    • How to encrypt the filename -> “standard”

    • Encrypt directory names -> “false”

    • Password -> yes or generate

    • Salt -> yes or generate

As listed above, the preference is to give it both the backendName and bucketName in the form b2-crypt:bucketname. This makes things easier for syncing the folders inside the bucket. You can simple encrypt it using b2-crypt:foldername instead of the longer b2-crypt:bucketname/foldername. I find this a bit cleaner as well.

Backing it Up

So far, we’ve setup Nextcloud to use an external volume, created an user for syncing the data and have created an encrypted backend with which we hope to sync the data to B2. Let’s turn that hope into reality.

The command that we’re going to do the syncing is:

rclone copy /mnt/volume-nbg-1-1/nextcloud b2-crypt:nextcloud --dry-run -v

dry-run and v are just there for debugging. In case everything runs fine, remove these options.

We are going to setup a cron job with clouduser to read and sync the data directory to the encrypted backend, everyday at 3:05AM.

Run the following command as a sudo user:

sudo -u clouduser crontab -e

This should open up a cron file in your default editor, add the following to it:

5 3 * * * rclone copy /mnt/volume-nbg-1-1/nextcloud b2-crypt:nextcloud

Further

As I mentioned, this post isn’t a complete walkthrough for the setup, but more like a skeleton. There are a couple of things you should be doing to have a stable and painless experience in case things go south:

Test the setup

Backup is not there for backing things up, but for restoring the data when the luck turns bad. So setup rclone in your local machine, sync some data back, and try to decrypt it. It should work, if it doesn’t then see where it went bad.

Have more than one backup

One problem with encryption is either of bitrot or of lost keys. Since we’re storing our data in someone else’s computer, it might make sense to encrypt it. But it’s always a good idea to have a local copy of it. With this setup, you have a (in case of Hetzner) triple replicated volume with non-encrypted data and another encrypted backup at B2. Make sure you have another local copy in your machine and/or external hard disk.

This blog post is just half backup

Nextcloud documentation says:

You must have both the database and data directory. You cannot complete restoration unless you have both of these.

So come up with a similar approach of backing up your Nextcloud’s database. The details are in the documentation. In my setup, I have a weekly cron job that backups up my database to B2.