One of the most visited pages on my blog is about how to automatically backup Docker volumes. In that post I use the Docker image
blacklabelops/volumerize. Unfortunately that image is deprecated since March 2019 and not longer maintained.
Under the hood the volumerize image is using the GNU program duplicity, which is an awesome software, but also has it’s downsides. Especially the model of full backups and incremental backups comes from a time where backups where mainly made to tapes (just append new files all the time). But now that we have storage (and cloud storage) where it’s also possible to delete or modify files, that isn’t the ideal solution anymore.
restic, which I now use instead, takes some ideas of git. It has a repository in it’s backup location and stores the files in blobs. Whenever you create a backup, it checks the index of blobs it already has and which new ones it should create. Then it creates a new snapshot referencing all blobs in this backup. If you have big files and only modify portions of it, it also helps that blobs have a limited size and big files get divided into multiple blobs.
Advantage of this model is, that it is possible to delete old snapshots without the need to do a new full backup. As long as the repo doesn’t get corrupted it’s sufficient to only do incremental backups, which can save you a lot of bandwidth.
A disadvantage when comparing restic and duplicity is that restic doesn’t support compression (yet), but it has strong encryption by default, so you need a password to backup and restore and if you forget that password your backups are lost.
But how do I actually backup my Docker volumes using restic?
I use the image
mazzolino/restic, which let’s you easily configure restic and sets a cronjob to run backups periodically. I currently use Backblaze Cloud Storage as backup location, because it’s quite cheap and pay-per-use.
The section in my
docker-compose.yml looks like this:
restic: container_name: restic image: mazzolino/restic hostname: docker environment: BACKUP_CRON: "0 0 2 * * *" RESTIC_REPOSITORY: b2:b2bucket:/restic RESTIC_PASSWORD: XXXXXXXXXX RESTIC_BACKUP_SOURCES: /source RESTIC_FORGET_ARGS: --keep-daily 7 --keep-weekly 4 B2_ACCOUNT_ID: XXXXXXXXXX B2_ACCOUNT_KEY: "XXXXXXXXXX" volumes: - forms:/source/forms:ro - kis3:/source/kis3:ro - ... other volumes ...
restic service has all important volumes I want to backup mounted under the
/source folder as read only, which is then selected as the backup origin. Every night at 2 o’clock a backup is running and backing up this folder to the location specified in
RESTIC_REPOSITORY. I’m using a B2 bucket, but restic supports many different targets. Also take a look at the other configuration options on the GitHub repository of this Docker image and the restic docs.
I also customized the Docker image to do a database dump before and just backup that dumped file, but I need to create a pull request with my modifications, to make it available for everyone…