Backup your docker containers with Borg Backup

How I backup my server with borgbackup

Install Borg backup

Borg backup is available on the package manager of the most common Linux based OS, for Debian you can use:

apt install borgbackup

If you are using OpenMediaVault, Borg Backup is available in the plugin section

Configure the first backup

Initialize the backup repository

Now that Borg backup is installed you can initialize a repository backup to store your datas, but first you need to create a passphrase. This passphrase will be used to manage your backups.

As a passphrase , you can use anything you want (password, passphrase), for my part I created a random 35 characters passphrase using OpenSSL.

openssl rand -base64 35
💡
Backup your passphrase, if you lost it, you will not be able to access your backups.

After that you can initialize your repository backup using the following command:

For local backups

Let's pretend we want our backup to be stored in the folder /mnt/backup

borg init -e repokey /mnt/backup

The passphrase will be asked during the initialization process

For remote backups (using SSH)

Let's pretend we want our backup to be stored in the folder /mnt/backup on a remote server.

borg init -e repokey user@backupserver:/mnt/backup
root@myserver:~# borg init -e repokey user@backupserver:/mnt/backup
user@server's password: #SSH-PASSWORD
Enter new passphrase: #PASSPHRASE
Enter same passphrase again: #PASSPHRASE
Do you want your passphrase to be displayed for verification? [yN]: n

When you use a remote backup, you will be asked for the SSH password and the passphrase during the initialization. I highly recommend you to create an SSH key between your server and the remote server used for backups.

To create a SSH key you can use the the following commands:

#Creating the private and public key
root@myserver:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:******************** root@myserver
The key s randomart image is:
+---[RSA 3072]----+
|     .           |
*
*
*
|   E..+ o        |
+----[SHA256]-----+

#Sending the public key to the backupserver
root@myserver:~# ssh-copy-id user@backupserver
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user@backupserver s password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user@backupserver'"
and check to make sure that only the key(s) you wanted were added.

Create first backup

To create your first backup you can use the following command (I added --statsand --progress to make it more verbose):

For local backups

borg create --stats --progress /mnt/backup::FirstBackup /folder/to/backup

For remote backups

borg create --stats --progress ssh://user@backupserver:/mnt/backup::FirstBackup /folder/to/backup

You can also backup different folders and / or files likes this:

borg create --stats --progress /mnt/backup::FirstBackup /folder/to/backup1 /folder/to/backup2 /path/file/to/backup.txt

On both case the passphrase will be asked and you should have the following output:

root@myserver:~# borg create --stats --progress /mnt/backup::FirstBackup /folder/to/backup
Enter passphrase for key /mnt/backup:
------------------------------------------------------------------------------
Repository: /mnt/backup
Archive name: FirstBackup
Archive fingerprint: e258b2292e02a59f49ee3b8e6b93bb2402ae28ff6c1091e292f9cacba2fa5769
Time (start): Mon, 2023-07-24 09:15:37
Time (end):   Mon, 2023-07-24 09:15:40
Duration: 2.55 seconds
Number of files: 1077
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:              227.36 MB             11.02 MB             10.15 MB
All archives:              227.36 MB             11.02 MB             10.22 MB

                       Unique chunks         Total chunks
Chunk index:                    1048                 1093
------------------------------------------------------------------------------

You can create incremental backups using the sames commands and changing the name of the backup:

borg create --stats --progress /mnt/backup::SecondBackup /folder/to/backup

Visualize the backups

Once you have backups done, there is some commands to see them and the storage used.

TIP: You can avoid to put your passphrase each time you use borg by using this command:

export BORG_PASSPHRASE='YOUR-PASSPHRASE'

It will work only during your current session, if you want to make it permanent add this line on your .profile or .bashrc to add your passphrase into your user environment variables.

See the list of available backups

#Local repository
borg list /mnt/backup

#Remote repository
borg list ssh://user@backupserver:/mnt/backup

Display the files inside a backup

#Local repository
borg list /mnt/backup::FirstBackup

#Remote repository
borg list ssh://user@backupserver:/mnt/backup::FirstBackup

Display the differences between 2 backups

#Local repository
borg diff /mnt/backup::FirstBackup SecondBackup

#Remote repository
borg diff ssh://user@backupserver:/mnt/backup::FirstBackup SecondBackup

Display infos about your backup repository

root@myserver:~# borg info /mnt/backup
Repository ID: 3f71dde670a90284dbe0dae81a9c300f7ba810b58c41839ffeeb81581a15082f
Location: /mnt/backup
Encrypted: Yes (repokey)
Cache: /root/.cache/borg/3f71dde670a90284dbe0dae81a9c300f7ba810b58c41839ffeeb81581a15082f
Security dir: /root/.config/borg/security/3f71dde670a90284dbe0dae81a9c300f7ba810b58c41839ffeeb81581a15082f
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
All archives:              454.71 MB             22.04 MB             10.22 MB

                       Unique chunks         Total chunks
Chunk index:                    1049                 2186

Pruning backup

To avoid having to many backups and fill up your hard drive, you can set a retention for the backup. Borg use the prune command

For example if you want to keep only 7 days of backup you can use this command

#Local repository
borg prune --keep-within 7d --list /mnt/backup

#Remote repository
borg prune --keep-within 7d --list ssh://user@backupserver:/mnt/backup

Automate the backups

OK, now we know how to take backups let's automate it all, for that I use a script. The script will perform the following actions

  • Stop all docker containers
  • Create a backup (the name of the backup will be the current date and hour)
  • Delete (prune) backups older than 7 days
  • Restart all the containers
#!/bin/bash

DATE=$(date +"%Y-%m-%d_%H:%M")
LOG="backup.log"
FOLDER_TO_BACKUP=/folder/to/backup
LOCAL_REPOSITORY=/mnt/backup
DOCKER_BIN=/usr/bin/docker ##Can be different depending how you installed docker, you can find it using the comand whereis docker
#REMOTE_REPOSITORY="ssh://user@backupserver:/mnt/backup"
export BORG_PASSPHRASE="YOUR_PASSPHRASE"

##
## Output to a logfile
##

exec > >(tee -i ${LOG})
exec 2>&1

echo "###### Backup started: $(date) ######"

echo "###### Stop docker containers"
$DOCKER_BIN compose stop
sleep 10


echo "###### Backup of $FOLDER_TO_BACKUP"
borg create -v --stats $LOCAL_REPOSITORY::$DATE \
  $FOLDER_TO_BACKUP

echo "###### Backup of $FOLDER_TO_BACKUP ended: $(date) ######"

echo "###### Start pruning  old backups : $(date) ######"
borg prune --keep-within 7d --list $LOCAL_REPOSITORY

echo "###### Pruning old backups ended : $(date) ######"

echo "###### Restart docker containers"
$DOCKER_BIN compose up -d

sleep 30

exit 0

Create a crontab to call this script and you are good to go !

Restore backups

There is different way to restore backups, but first we need to know the name of the backup and the one we want to restore

List the backups

#Local repository
borg list /mnt/backup

#Remote repository
borg list ssh://user@backupserver:/mnt/backup

On the previous example we created backup named FirstBackup and a second one named SecondBackup

So you should have something like this

root@myserver:~# borg list /mnt/backup
FirstBackup                          Mon, 2023-07-24 09:15:37 [e258b2292e02a59f49ee3b8e6b93bb2402ae28ff6c1091e292f9cacba2fa5769]
SecondBackup                         Mon, 2023-07-24 09:36:46 [f50ab726dcd6eb73eabd069aad8e4a2279d59a2554d80d5dc4c7bdc3f302d1e7]

Retore a complete backup

To restore the SecondBackup you can use the command

#Local repository
borg extract -v --list /mnt/backup::SecondBackup

#Remote repository
borg extract -v --list ssh://user@backupserver:/mnt/backup::SecondBackup

This will restore the backup on the current folder.

Restore a specific folder or file

#Local repository
#Restore a folder
borg extract -v --list /mnt/backup::SecondBackup /folder/to/backup/folder/to/restore
#Restore a file
borg extract -v --list /mnt/backup::SecondBackup /folder/to/backup/file_to_restore

#Remote repository
#Restore a folder
borg extract -v --list ssh://user@backupserver:/mnt/backup::SecondBackup /folder/to/backup/folder/to/restore
#Restore a file
borg extract -v --list ssh://user@backupserver:/mnt/backup::SecondBackup /folder/to/backup/file_to_restore

This command will restore the folder / file on the current folder.

Mount a backup

Something interesting with borg is you can mount a backup as a folder on your server/computer to visualize or restore datas.

To mount SecondBackup in the folder /tmp/restore

mkdir /tmp/restore

#Local repository
borg mount /mnt/backup::SecondBackup /tmp/restore

#Remote repository
borg mount ssh://user@backupserver:/mnt/backup::SecondBackup /tmp/restore

You can access the folder /tmp/restore and from there you can read  and / or copy the files / folder you want to retrieves.

If you don't specify the backup you want to mount you will mount all the backups

root@myserver:~# borg mount /mnt/backup /tmp/restore/
root@myserver:~# ls -lttr /tmp/restore/
total 0
drwxr-xr-x 1 root root 0 Jul 24 09:15 FirstBackup
drwxr-xr-x 1 root root 0 Jul 24 09:36 SecondBackup

Umount a backup

You can umount the backup using

borg umount /tmp/restore/

Delete backup and repository

Delete backup

If you want to delete a backup you can use the command borg delete, here an exemple todelete SecondBackup

#Local repository
borg delete /mnt/backup::SecondBackup

#Remote repository
borg delete ssh://user@backupserver:/mnt/backup::SecondBackup

Delete a repository

It' s the same command but without specifying a backup

#Local repository
borg delete /mnt/backup

#Remote repository
borg delete ssh://user@backupserver:/mnt/backup

Exemple:

root@myserver:~# borg delete /mnt/backup
You requested to completely DELETE the following repository *including* 4 archives it contains:
------------------------------------------------------------------------------
Repository ID: 3f71dde670a90284dbe0dae81a9c300f7ba810b58c41839ffeeb81581a15082f
Location: /mnt/backup
------------------------------------------------------------------------------
Type 'YES' if you understand this and want to continue: YES

Sources:

Quick Start — Borg - Deduplicating Archiver 1.2.4 documentation