clean up borg backup notes

This commit is contained in:
2026-02-06 20:20:56 -05:00
parent fb19c81d47
commit 2b62ad0956
5 changed files with 80 additions and 127 deletions

View File

@@ -1,12 +1,12 @@
[Unit] [Unit]
Description=Runs backup script for {{ repo_name }} Description=Runs the Borg backup script at /usr/local/script/borg-backup.sh
After=network.target After=network.target
Wants=network-online.target Wants=network-online.target
[Service] [Service]
Restart=no Restart=no
Type=oneshot Type=oneshot
ExecStart=/usr/local/script/backup-{{ repo_name }}.sh ExecStart=/usr/local/script/borg-backup.sh
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,5 +1,7 @@
#!/bin/sh #!/bin/sh
set -x
{% for service in stop_services %} {% for service in stop_services %}
systemctl stop {{ service }} systemctl stop {{ service }}
{% endfor %} {% endfor %}
@@ -8,8 +10,12 @@ systemctl stop {{ service }}
systemctl --user --machine={{ systemd_user }}@.host stop {{ service }} systemctl --user --machine={{ systemd_user }}@.host stop {{ service }}
{% endfor %} {% endfor %}
{% for compose in docker_compose_down %}
docker compose -f {{compose}} down
{% endfor %}
# Setting this, so the repo does not need to be given on the commandline: # Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO={{ borg_user }}@{{ borg_host }}:{{ repo_name }} export BORG_REPO={{ borg_user }}@{{ borg_host }}:.
# See the section "Passphrase notes" for more infos. # See the section "Passphrase notes" for more infos.
export BORG_PASSPHRASE={{ borg_passphrase }} export BORG_PASSPHRASE={{ borg_passphrase }}
@@ -34,6 +40,7 @@ borg create \
--exclude 'home/*/.cache/*' \ --exclude 'home/*/.cache/*' \
--exclude 'var/tmp/*' \ --exclude 'var/tmp/*' \
--exclude 'home/*/.snapshots/*' \ --exclude 'home/*/.snapshots/*' \
--exclude 'home/.snapshots/*' \
{% for dir in exclude_dirs %} {% for dir in exclude_dirs %}
--exclude '{{ dir }}' \ --exclude '{{ dir }}' \
{% endfor %} {% endfor %}
@@ -53,6 +60,10 @@ systemctl start {{ service }}
systemctl --user --machine={{ systemd_user }}@.host start {{ service }} systemctl --user --machine={{ systemd_user }}@.host start {{ service }}
{% endfor %} {% endfor %}
{% for compose in docker_compose_down %}
docker compose -f {{compose}} up -d
{% endfor %}
info "Pruning repository" info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly

View File

@@ -1,11 +1,11 @@
[Unit] [Unit]
Description=Run Backup backup-{{ repo_name }}.service every day Description=Run Backup borg-backup.service every day
[Timer] [Timer]
OnCalendar=*-*-* 2:00:00 OnCalendar=*-*-* 2:00:00
AccuracySec=10min AccuracySec=10min
Persistent=true Persistent=true
Unit=backup-{{ repo_name }}.service Unit=borg-backup.service
[Install] [Install]
WantedBy=timers.target WantedBy=timers.target

View File

@@ -2,9 +2,7 @@
- [Borg Backup](#borg-backup) - [Borg Backup](#borg-backup)
- [Install Borg](#install-borg) - [Install Borg](#install-borg)
- [Set up a laptop or workstation client](#set-up-a-laptop-or-workstation-client) - [Set up a new client](#set-up-a-new-client)
- [Set up a new server client](#set-up-a-new-server-client)
- [Create a Backup Service](#create-a-backup-service)
- [Check backup service logs](#check-backup-service-logs) - [Check backup service logs](#check-backup-service-logs)
- [Run a Manual Backup](#run-a-manual-backup) - [Run a Manual Backup](#run-a-manual-backup)
- [Back up and Entire System](#back-up-and-entire-system) - [Back up and Entire System](#back-up-and-entire-system)
@@ -31,11 +29,22 @@ touch /home/backup/.ssh/authorized_keys
chown -R backup:backup /home/backup/.ssh chown -R backup:backup /home/backup/.ssh
``` ```
## Set up a laptop or workstation client ## Set up a new client
For backing up your laptop or personal account. Clients will either use a backup app (Pika) or the `backup.sh.j2` script in this
directory.
1. On your personal account, set up the borg connection We'll be using ssh authorized keys to control where the repo gets created. This
keeps client configuration simple, since clients will just need to reference
their repo at `.` rather than an absolute path.
For pika, you can set the backup location to something like `borg-backup:.`
(assuming you have an entry matching `borg-backup` in your `.ssh/config`)
Backups will be run as the root user. Generate them an SSH key to connect to the borg server.
1. On the client server, install borg. On Fedora this is `dnf install borgbackup`.
2. On the client server as root (or as the laptop user, for pika), create an SSH key for borg
```bash ```bash
export BACKUP_HOST="borg.reeselink.com" export BACKUP_HOST="borg.reeselink.com"
@@ -49,97 +58,29 @@ For backing up your laptop or personal account.
User backup User backup
Port 22 Port 22
EOF EOF
echo "export CLIENT_FQDN=${USER}.${HOSTNAME}.reeselink.com"
echo "export SSH_PUBKEY=\"$(cat ~/.ssh/id_${BACKUP_HOST}.pub)\""
``` ```
2. On the borg backup server as the backup user: 3. On borg.reeselink.com as the `backup` user, allow that SSH key to access the repo
```bash ```bash
# Use echo from above # Fill these out
export CLIENT_FQDN= export CLIENT_HOSTNAME="fqdn.reeseapps.com"
export SSH_PUBKEY=
# Create the authkey entry to restrict the user's access to the borg repo folder
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
# Create the directory
mkdir repos/${CLIENT_FQDN}
```
3. On your personal account, create the repo and your first backup
```bash
# Do not include the first / in the path
export PATH_TO_BACKUP=home/${USER}
export BACKUP_HOST="borg.reeselink.com"
export BORG_REPO=${BACKUP_HOST}:home
# If not initialized, do that now
borg init --encryption none $BORG_REPO
borg list
# Run backup and timestamp it
borg create \
--verbose \
--filter AME \
--list \
--stats \
--progress \
--show-rc \
--compression lz4 \
--exclude-caches \
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
/${PATH_TO_BACKUP}
# Mount a borg archive
borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/
# Restore a borg archive to a location (dry run)
# First, cd to the location you want to extract to
cd ~
# Then, extract to that location. --strip-components takes the first n items off a path
borg extract --dry-run --list --strip-components 2 $BORG_REPO::my-files home/USERNAME
```
## Set up a new server client
Backups will be run as the root user. Generate them an SSH key to
On the server as root:
```bash
export BACKUP_HOST="borg.reeselink.com"
ssh-keygen -C root@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
cat <<EOF >> ~/.ssh/config
Host ${BACKUP_HOST}
Hostname ${BACKUP_HOST}
IdentityFile ~/.ssh/id_${BACKUP_HOST}
User backup
Port 22
EOF
```
Now on borg.reeselink.com as root:
```bash
export CLIENT_FQDN="fqdn.reeseapps.com"
export SSH_PUBKEY="ssh-rsa abcd1234 backup@fqdn.something.com" export SSH_PUBKEY="ssh-rsa abcd1234 backup@fqdn.something.com"
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
# Just copy and paste these
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_HOSTNAME}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_HOSTNAME}"
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}" export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
mkdir /home/backup/repos/${CLIENT_FQDN} # Inspect the authkey entry
chown -R backup:backup /home/backup/repos/${CLIENT_FQDN} echo $AUTHKEY_ENTRY
# add the authkey entry to authorized_keys and create the repo dir
echo $AUTHKEY_ENTRY >> ~/.ssh/authorized_keys
mkdir /home/backup/repos/${CLIENT_HOSTNAME}
``` ```
## Create a Backup Service 4. On the client server, `ssh borg.reeselink.com` to accept the SSH key
5. Create the vars file for your client in `secrets/host_vars.yaml` like the following
Create your vars file in `secrets/host_vars.yaml`
```yaml ```yaml
repo_name: my_repo repo_name: my_repo
@@ -155,17 +96,18 @@ keep_monthly: 1
stop_services: [] stop_services: []
stop_user_services: stop_user_services:
- foobar - foobar
docker_compose_down:
- /root/release-compose.yaml
``` ```
6. Create the backup task with ansible
```bash ```bash
# Update all existing backup services for podman
for var_file in $(ls active/systemd_borg/secrets); do
ansible-playbook \ ansible-playbook \
-i ansible/inventory.yaml \ -i ansible/inventory.yaml \
-l 3dserver \ -l deskwork-root \
active/systemd_borg/install_backup.yaml \ active/software_borg/install_backup.yaml \
-e "@active/systemd_borg/secrets/$var_file" -e "@active/software_borg/secrets/ai.deskwork_vars.yaml"
done
``` ```
## Check backup service logs ## Check backup service logs

View File

@@ -8,32 +8,32 @@
path: /usr/local/script path: /usr/local/script
state: directory state: directory
mode: '0755' mode: '0755'
- name: Copy backup-{{ repo_name }}.service - name: Copy borg-backup.service
template: template:
src: backup.service src: backup.service
dest: /etc/systemd/system/backup-{{ repo_name }}.service dest: /etc/systemd/system/borg-backup.service
owner: root owner: root
group: root group: root
mode: '0644' mode: '0644'
- name: Copy backup-{{ repo_name }}.timer - name: Copy borg-backup.timer
template: template:
src: backup.timer src: backup.timer
dest: /etc/systemd/system/backup-{{ repo_name }}.timer dest: /etc/systemd/system/borg-backup.timer
owner: root owner: root
group: root group: root
mode: '0644' mode: '0644'
- name: Template backup-{{ repo_name }}.sh - name: Template borg-backup.sh
template: template:
src: backup.sh.j2 src: backup.sh.j2
dest: /usr/local/script/backup-{{ repo_name }}.sh dest: /usr/local/script/borg-backup.sh
owner: root owner: root
group: root group: root
mode: '0744' mode: '0744'
- name: Initialize Repo {{ borg_user }}@{{ borg_host }}:{{ repo_name }} - name: Initialize Repo {{ borg_user }}@{{ borg_host }}:.
script: /usr/bin/borg init -e none {{ borg_user }}@{{ borg_host }}:{{ repo_name }} script: /usr/bin/borg init -e none {{ borg_user }}@{{ borg_host }}:.
ignore_errors: yes ignore_errors: yes
- name: Reload backup timer backup-{{ repo_name }}.timer - name: Reload backup timer borg-backup.timer
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
name: backup-{{ repo_name }}.timer name: borg-backup.timer
enabled: true enabled: true
daemon_reload: true daemon_reload: true