Setup backups with Borg Backup Tool

Borg backup is a great tool to do encrypted, incremental and compressed backup repositories for Linux and Mac. Lately i played with a new backup tool named Borg that satisfy my requirements to do decentralized, encrypted, compressed backups.

First of all init the backup folder, named repo in borg, because it create an incremental repository that stores only the incremental diff of the files stored in the backup (similarly but not as the same of a git repo).

Also the repository can be accessed via ssh to backup a local machine in a remote one.

Create our first backup

Create a folder named backup_folder and init the backup repository

init create the folder and initialize the repository with the repokey mode, the repo is encrypted and can be accessed with a password (read more on the encryption options).

Now run our first backup (i created some random files with this script). The ::1 part means that our backup is named 1 inside the backup_folder.

The output will look like this:

------------------------------------------------------------------------------                                                               
Archive name: 1
Archive fingerprint: 1e6cb5b4cb55b8d4c666ed3b15e6ff5a2693969096ff66a462f98efb194cf345
Time (start): Mon, 2018-11-19 17:57:04
Time (end):   Mon, 2018-11-19 17:57:04
Duration: 0.02 seconds
Number of files: 15
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:              273.97 kB            273.71 kB            273.71 kB
All archives:              273.97 kB            273.71 kB            273.71 kB

                       Unique chunks         Total chunks
Chunk index:                      17                   17
------------------------------------------------------------------------------

Now create some more files and run another backup

We can list now the executed backups

And the ouput

Enter passphrase for key backup_folder: 
1                                    Mon, 2018-11-19 17:57:04 [1e6cb5b4cb55b8d4c666ed3b15e6ff5a2693969096ff66a462f98efb194cf345]
2                                    Mon, 2018-11-19 18:02:12 [20130e7014ec4dc8b3e32d67fea881313c64fb1fdbda6fa054866995d3a1f2af]

We can also diff the backups

And the output

Enter passphrase for key backup_folder: 
 +18.3 kB   -7.1 kB folder_to_backup/file001.bin
 +28.3 kB  -19.3 kB folder_to_backup/file002.bin
...
added       8.47 kB folder_to_backup/file016.bin
added      26.67 kB folder_to_backup/file017.bin
...

Useful features

To automate the creation of the backups names we can use the special variables {hostname} and {now}

There’s also a magic function that allow to mount in the filesystem (with fuse) a specific backup

You can also export a tar of a backup

or only a subfolder inside the backup

And you can dump directly inside borg repo

And to remove the backups older than 7 days, keep 1 backup a week for 4 weeks and 1 backup a month for 6 months

Automate it

You can automate the backups via cron with this simple script taken from HERE (reported here for completeness)

#!/bin/sh

# Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO=ssh://username@example.com:2022/~/backup/main

# Setting this, so you won't be asked for your repository passphrase:
export BORG_PASSPHRASE='XYZl0ngandsecurepa_55_phrasea&&123'
# or this to ask an external program to supply the passphrase:
export BORG_PASSCOMMAND='pass show backup'

# some helpers and error handling:
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM

info "Starting backup"

# Backup the most important directories into an archive named after
# the machine this script is currently running on:

borg create                         \
    --verbose                       \
    --filter AME                    \
    --list                          \
    --stats                         \
    --show-rc                       \
    --compression lz4               \
    --exclude-caches                \
    --exclude '/home/*/.cache/*'    \
    --exclude '/var/cache/*'        \
    --exclude '/var/tmp/*'          \
                                    \
    ::'{hostname}-{now}'            \
    /etc                            \
    /home                           \
    /root                           \
    /var                            \

backup_exit=$?

info "Pruning repository"

# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-' prefix is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:

borg prune                          \
    --list                          \
    --prefix '{hostname}-'          \
    --show-rc                       \
    --keep-daily    7               \
    --keep-weekly   4               \
    --keep-monthly  6               \

prune_exit=$?

# actually free repo disk space by compacting segments

borg compact

compact_exit=$?

# use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))

if [ ${global_exit} -eq 1 ];
then
    info "Backup, Prune and/or Compact finished with a warning"
fi

if [ ${global_exit} -gt 1 ];
then
    info "Backup, Prune and/or Compact finished with an error"
fi

exit ${global_exit}