Installation | Maintenance | Beyond Lino

How to set up a Borg backup client and server

Installation

For example we have a backup server named backup-server.net and a client server named site1 (which is not a domain name, just an account name on the backup server).

On the client:

$ sudo apt install borgbackup
$ sudo ssh-keygen -t rsa

When asked for a passphrase, leave it empty because this key will be used by a cron job. The key will be saved to /root/.ssh/id_rsa.

On the server, install borgbackup, create user site1:

$ sudo apt install borgbackup
$ sudo adduser --disabled-password site1
$ sudo su - site1
$ mkdir backups
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
$ cat >> .ssh/authorized_keys

Paste the client’s public key to the terminal. Press ENTER to add at least one newline. Press Ctrl+D to say you’re finished with pasting content.

Back on the client:

Create a file /usr/local/bin/backup2borg.sh with this content:

#!/bin/sh
# set -e  # do *not* exit on error because we want mysql to restart even when
# the backup failed.
# Inspired from https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups

export BORG_REPO=myserver@backup-server.net:/home/myserver/backups
export BORG_PASSPHRASE=`cat /root/backup2borg_passwd`

echo "Make snapshots"
# service supervisor stop
/usr/local/lino/lino_local/first/make_snapshot.sh
/usr/local/lino/lino_local/second/make_snapshot.sh

echo "Stop mysql"
service mysqld stop

echo "Start backup"
borg create                         \
    --filter AME                    \
    --compression lz4               \
    --exclude-caches                \
    --exclude '/home/*/.cache/*'    \
    --exclude '/var/backups/*'      \
    --exclude '*/env'               \
    --exclude '*/tmp/*'             \
    --exclude '*/log'               \
    --exclude '*/snapshot.zip'      \
    --exclude '*/repositories/*'    \
    --exclude '*/cache/*'           \
    --exclude '*/__pycache__/*'     \
    --exclude '*/t/*'               \
    ::'{hostname}-{now}'            \
    /etc                            \
    /home                           \
    /root                           \
    /usr/local                      \
    /var                            \

echo "Restart mysqld"
service mysqld start

echo "Remove old backups"
borg prune                          \
    --prefix '{hostname}-'          \
    --keep-daily    6               \
    --keep-weekly   3               \
    --keep-monthly  5               \

Write your Borg passphrase into a file named /root/backup2borg_passwd and make the file readable only by root:

$ sudo nano /root/backup2borg_passwd
$ sudo chmod go-r /root/backup2borg_passwd

Create the Borg repository:

$ sudo su
# export BORG_REPO=site1@backup-server.net:/home/site1/backups
# export BORG_PASSPHRASE=`cat /root/backup2borg_passwd`
# borg init --encryption=repokey-blake2

Hit Ctrl+D to terminate the sudo session and to remove the environment variables. Make a manual backup to see whether it works:

$ sudo /usr/local/bin/backup2borg.sh

Check whether your backup worked:

$ sudo borg mount site1@backup-server.net:/home/site1/backups ~/site1

This should ask you interactively for your passphrase (the one you stored in your /root/backup2borg_passwd).

To make it run automatically every day, create a file /etc/cron.daily/backup2borg with this content:

#!/bin/sh
/usr/local/bin/backup2borg.sh > /dev/null

Restoring a backup to another machine

Now imagine that your original server, site1 no longer exists. The ssh key is gone, nobody will ever log in as site1 to your backup server. Of course you can log in as root, and you know the passphrase.

Copy your public SSH key to the .ssh/authorized_keys of site1 on backup-server.net.

$ sudo apt install borgbackup
$ borg mount site1@backup-server.net:/home/site1/backups ~/myborg

Now you can see all available backups under ~/myborg. This is a read-only file system, so if you want to use the files, you need to copy them somewhere else. And you must copy them as root because of file permissions. Let’s imagine you want to restore the backup 2023-10-06T06:30:05. But where to copy them? Short answer: into an existing Lino site that has been setup using getlino.

So here is what you do:

$ getlino startsite avanti site2
$ cd ~/myborg/site1-2023-10-06T06:30:05
$ sudo cp -r snapshot media /usr/local/lino/site2/

Now edit the two settings.py files (the one from the backup and the one created by getlino). Basically you overwrite most of the newly created settings by the content from the backup, except for the DATABASES setting (which you leave as getlino created it).

$ go site2 $ pm run snapshot/restore.py $ pm run buildcache $ pm run collectstatic

In other words, we leave the getlino version of the files manage.py, asgi.py and make_snapshot.sh.

Notes

The first time ssh will ask you to confirm that IP address and server name are correct:

The authenticity of host 'backup-server.net (backup-server.net)' can't be established.
ECDSA key fingerprint is SHA256:/xxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'backup-server.net' (ECDSA) to the list of known hosts.

You can also log in manually:

$ sudo ssh site1@backup-server.net