32 Commits

Author SHA1 Message Date
Erik Westrup
cf978b00fe Modified: CHANGELOG.md 2022-02-01 13:08:49 +01:00
Erik Westrup
db27be517f Modified: CHANGELOG.md 2022-02-01 13:08:28 +01:00
Erik Westrup
3c9fa21b2e Modified: CHANGELOG.md 2022-02-01 13:07:55 +01:00
Gerard Bosch
d8f25cdf88 Multiple profile configuration (#45)
Adds possibility to have multiple profiles with different backup paths, retention etc.

Co-authored-by: Matt Feifarek <matt.feifarek@gmail.com>
Co-authored-by: Erik Westrup <erik.westrup@gmail.com>
2022-02-01 10:09:36 +01:00
Erik Westrup
16dbe699ab Revert "Empty line"
This reverts commit a011bb6dd2.
2022-01-30 20:09:26 +01:00
Erik Westrup
a011bb6dd2 Empty line 2022-01-30 20:09:07 +01:00
Erik Westrup
15a02d4bd3 Add note about Make as recommended reqirements for installing 2022-01-19 12:02:20 +01:00
Erik Westrup
3a51ffb795 Modified: README.md 2022-01-18 12:01:58 +01:00
Erik Westrup
1b57069d30 README: anecdotal pricing 2022-01-18 12:00:29 +01:00
Erik Westrup
5eeab95c84 Create backup of existing config files on install 2022-01-17 15:53:17 +01:00
Erik Westrup
3e22d8f99d Remove local generated files from templates
As discussed in #46, it's not necessary to keep the local files
generated from the templates as the users should edit the installed
confs, not in the git.
2022-01-17 15:51:39 +01:00
Erik Westrup
9cb85a8571 Add notes to README about development 2022-01-17 15:51:33 +01:00
Erik Westrup
7141426699 Spell 2022-01-17 13:26:08 +01:00
Erik Westrup
9e292218cf Spell fix 2022-01-17 13:16:49 +01:00
Erik Westrup
546845c687 Merge pull request #48 from erikw/fix/46
Fix make install failing when run multiple times
2022-01-17 09:52:08 +01:00
Erik Westrup
828ff79e7a Fix make install failing when run multiple times
Due to the security feature preventing checking in B2 credentials to
git, the install target would get the same file twice due to pattern
subsitution.

This issue is not visible with BSD install as it ignores the issue, but
GNU install wil fail.

Fixes #46
2022-01-16 20:59:50 +01:00
Erik Westrup
8932e60e4a Spell fixes 2022-01-16 20:56:00 +01:00
Erik Westrup
36a90b963e Fix URL 2022-01-01 13:59:45 +01:00
Erik Westrup
5a3c8afb43 Link to #44
Fixes #44
2022-01-01 13:58:33 +01:00
Erik Westrup
aff6211407 Modified: README.md 2021-12-18 11:11:11 +01:00
Erik Westrup
3e9233c0fc Merge pull request #43 from erikw/fix/42
Add comment explaining dynamic backup path
2021-12-04 18:40:35 +01:00
Erik Westrup
1d1145296d Add comment explaining dynamic backup path
Fixes #42
2021-12-04 18:38:34 +01:00
Erik Westrup
ceac35abc8 Remove SLOC badge 2021-12-03 19:51:24 +01:00
Erik Westrup
d01d2995f5 Update CHANGELOG.md 2021-12-03 18:40:24 +01:00
Erik Westrup
97a9475550 Update CHANGELOG.md 2021-12-03 18:35:51 +01:00
Erik Westrup
2e55d1cfef Modified: CHANGELOG.md 2021-12-03 18:35:07 +01:00
Erik Westrup
7a8861adc4 Merge pull request #41 from erikw/fix/40
Fix installation of template files
2021-12-03 18:32:26 +01:00
Erik Westrup
bf9b29575a Update README.md 2021-12-03 18:16:39 +01:00
Erik Westrup
428f4be872 Fix installation of template files
The target that copies the *.template files (#15) had a '/' prefixed which
should not be there. The copy should be locally here. The real install
happens in the install-conf that respects $PREFIX

Fixes #40
2021-12-03 17:09:14 +01:00
Erik Westrup
99f4ba4436 Add AUR maintainer badge 2021-12-02 15:31:33 +01:00
Erik Westrup
ae2b122134 Add AUR instructions 2021-12-02 15:28:40 +01:00
Erik Westrup
8e1853458c Add AUR badge 2021-12-02 15:26:55 +01:00
16 changed files with 261 additions and 113 deletions

12
.gitignore vendored
View File

@@ -1,2 +1,10 @@
/etc/restic/b2_pw.txt
/etc/restic/b2_env.sh
# Prevent check-in of these sensitive files. Instead they are generated from the corresponding *.template file.
etc/restic/pw.txt
etc/restic/_global.env
etc/restic/default.env
# IntelliJ
.idea/
*.iml
# VSCode
.vscode/

View File

@@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [2.0.0] - 2022-02-01
### Changed
- **BREAKING CHANGE** [#45](https://github.com/erikw/restic-systemd-automatic-backup/pull/45): multiple backup profiles are now supported. Please backup your configuration before upgrading. The setup of configuration files are now laied out differently. See the [README.md](README.md) TL;DR setup section.
- `restic_backup.sh` has had variables extracted to profiles instead, to allow for configuration of different backups on the same system.
- `b2_env.sh` is split to two files `_global.env` and `default.env` (the default profile). `_global.env` will have B2 accountID and accountKey and `default.env` has backup paths, and retention.
- `b2_pw.sh` renamed to pw.txt
### Fixed
- `restic_backup.sh` now finds `.backup_exclude` files on each backup path as intended.
## [1.0.1] - 2021-12-03
### Fixed
- $(make install) now works for the *.template files ([#40](https://github.com/erikw/restic-systemd-automatic-backup/issues/40))
## [1.0.0] - 2021-12-02
It's time to call this a proper major version!
@@ -19,4 +33,4 @@ It's time to call this a proper major version!
- Conflicts for restic-check service
## [0.1.0] - 2019-07-23
- First tagged version.
- First tagged version to allow Arch's AUR to download a tarball archive to install.

View File

@@ -3,17 +3,18 @@
### Macros ###
SRCS_SCRIPTS = $(filter-out %cron_mail, $(wildcard usr/local/sbin/*))
SRCS_CONF = $(filter-out %template, $(wildcard etc/restic/*))
# $(sort) remove duplicates that comes from running make install >1 times.
SRCS_CONF = $(sort $(patsubst %.template, %, $(wildcard etc/restic/*)))
SRCS_SYSTEMD = $(wildcard etc/systemd/system/*)
# Just set PREFIX in envionment, like
# $ PREFIX=/tmp/test make
# To change the installation root path, set the PREFIX variable in your shell's environment, like:
# $ PREFIX=/usr/local make install
# $ PREFIX=/tmp/test make install
DEST_SCRIPTS = $(PREFIX)/usr/local/sbin
DEST_CONF = $(PREFIX)/etc/restic
DEST_SYSTEMD = $(PREFIX)/etc/systemd/system
INSTALLED_FILES = $(addprefix $(PREFIX)/, $(SRCS_SCRIPTS) $(SRCS_CONF) $(SRCS_SYSTEMD)) \
$(DEST_CONF)/b2_env.sh $(DEST_CONF)/b2_pw.txt
INSTALLED_FILES = $(addprefix $(PREFIX)/, $(SRCS_SCRIPTS) $(SRCS_CONF) $(SRCS_SYSTEMD))
### Targets ###
# target: all - Default target.
@@ -32,24 +33,25 @@ install-scripts:
install -d $(DEST_SCRIPTS)
install -m 0744 $(SRCS_SCRIPTS) $(DEST_SCRIPTS)
etc/restic/b2_env.sh:
install -m 0600 etc/restic/b2_env.sh.template /etc/restic/b2_env.sh
etc/restic/b2_pw.txt:
install -m 0600 etc/restic/b2_pw.txt.template /etc/restic/b2_pw.txt
# Copy templates to new files with restricted permissions.
# Why? Because the non-template files are git-ignored to prevent that someone who clones or forks this repo checks in their sensitive data like the B2 password!
etc/restic/_global.env etc/restic/default.env etc/restic/pw.txt:
install -m 0600 $@.template $@
# target: install-conf - Install restic configuration files.
# will create these files locally only if they don't already exist
install-conf: | etc/restic/b2_env.sh etc/restic/b2_pw.txt
# `|` means that dependencies are order-only, i.e. only created if they don't already exist.
install-conf: | $(SRCS_CONF)
install -d $(DEST_CONF)
install -m 0600 $(SRCS_CONF) $(DEST_CONF)
install -b -m 0600 $(SRCS_CONF) $(DEST_CONF)
$(RM) etc/restic/_global.env etc/restic/default.env etc/restic/pw.txt
# target: install-systemd - Install systemd timer and service files
# target: install-systemd - Install systemd timer and service files.
install-systemd:
install -d $(DEST_SYSTEMD)
install -m 0644 $(SRCS_SYSTEMD) $(DEST_SYSTEMD)
# target: uninstall - Uninstall files from the install targets
# target: uninstall - Uninstall ALL files from the install targets.
uninstall:
@for file in $(INSTALLED_FILES); do \
echo $(RM) $$file; \

161
README.md
View File

@@ -2,11 +2,12 @@
[![GitHub Stars](https://img.shields.io/github/stars/erikw/restic-systemd-automatic-backup?style=social)](#)
[![GitHub Forks](https://img.shields.io/github/forks/erikw/restic-systemd-automatic-backup?style=social)](#)
<br>
[![SLOC](https://img.shields.io/tokei/lines/github/erikw/restic-systemd-automatic-backup)](#)
[![AUR version](https://img.shields.io/aur/version/restic-systemd-automatic-backup)](https://aur.archlinux.org/packages/restic-systemd-automatic-backup/)
[![AUR maintainer](https://img.shields.io/aur/maintainer/restic-systemd-automatic-backup?label=AUR%20maintainer)](https://aur.archlinux.org/packages/restic-systemd-automatic-backup/)
[![Open issues](https://img.shields.io/github/issues/erikw/restic-systemd-automatic-backup)](https://github.com/erikw/restic-systemd-automatic-backup/issues)
[![Closed issues](https://img.shields.io/github/issues-closed/erikw/restic-systemd-automatic-backup?color=success)](https://github.com/erikw/restic-systemd-automatic-backup/issues?q=is%3Aissue+is%3Aclosed)
[![Closed PRs](https://img.shields.io/github/issues-pr-closed/erikw/restic-systemd-automatic-backup?color=success)](https://github.com/erikw/restic-systemd-automatic-backup/pulls?q=is%3Apr+is%3Aclosed)
[![License](https://img.shields.io/badge/license-BSD--3-blue)](LICENSE.txt)
[![License](https://img.shields.io/badge/license-BSD--3-blue)](LICENSE)
[![OSS Lifecycle](https://img.shields.io/osslifecycle/erikw/restic-systemd-automatic-backup)](https://github.com/Netflix/osstracker)
[![Latest tag](https://img.shields.io/github/v/tag/erikw/restic-systemd-automatic-backup)](https://github.com/erikw/restic-systemd-automatic-backup/tags)
<br>
@@ -18,82 +19,155 @@
# Intro
[restic](https://restic.net/) is a command-line tool for making backups, the right way. Check the official website for a feature explanation. As a storage backend, I recommend [Backblaze B2](https://www.backblaze.com/b2/cloud-storage.html) as restic works well with it, and it is (at the time of writing) very affordable for the hobbyist hacker!
[restic](https://restic.net/) is a command-line tool for making backups, the right way. Check the official website for a feature explanation. As a storage backend, I recommend [Backblaze B2](https://www.backblaze.com/b2/cloud-storage.html) as restic works well with it, and it is (at the time of writing) very affordable for the hobbyist hacker! (anecdotal: I pay for my full-systems backups each month typically < 1 USD).
Unfortunately restic does not come pre-configured with a way to run automated backups, say every day. However it's possible to set this up yourself using systemd/cron and some wrappers. This example also features email notifications when a backup fails to complete.
Here follows a step-by step tutorial on how to set it up, with my sample script and configurations that you can modify to suit your needs.
Note, you can use any of the supported [storage backends](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html). The setup should be similar but you will have to use other configuration variables to match your backend of choice.
# Requirements
* `restic >=v0.9.6`
* (recommended) `make` if you want an automated install
* Arch: part of the `base-devel` meta package, Debian/Ubuntu: part of the `build-essential` meta package, macOS: preinstalled make works)
# Set up
# TL;DR Setup
1. Create B2 credentials as instructed [below](#1-create-backblaze-b2-account)
1. Install config and scripts:
```console
$ sudo make install
```
☝ **Note**: `sudo` is required here, as some files are installed into system directories (`/etc/`
and `/usr/sbin`). Have a look to the `Makefile` to know more.
1. Fill out configuration values (edit with sudo):
* `/etc/restic/pw.txt` - Contains the password (single line) to be used by restic to encrypt the repository files. Should be different than your B2 password!
* `/etc/restic/_global.env` - Global environment variables.
* `/etc/restic/default.env` - Profile specific environment variables (multiple profiles can be defined by copying to `/etc/restic/something.env`).
* `/etc/restic/backup_exclude` - List of file patterns to ignore. This will trim down your backup size and the speed of the backup a lot when done properly!
1. Initialize remote repo as described [below](#3-initialize-remote-repo)
1. Configure [how often](https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events) back up should be made.
* Edit if needed `OnCalendar` in `/etc/systemd/system/restic-check@.timer`.
1. Enable automated backup for starting with the system (`enable` creates symlinks):
```console
$ sudo systemctl start restic-backup@default.timer
$ sudo systemctl enable restic-backup@default.timer
```
1. And run an immediate backup if you want (if not, it will run on daily basis):
```console
$ sudo systemctl start restic-backup@default
```
1. Watch its progress with Systemd journal:
```console
$ journalctl -f --lines=50 -u restic-backup@default
```
1. Verify the backup
```console
$ sudo -i
$ source /etc/restic/default.env
$ restic snapshots
```
1. (optional) Define multiple profiles: just make a copy of the `default.env` and use the defined profile name in place of `default` to run backups or enable timers. Notice that the value after `@` works as a parameter.
1. (optional) Enable the check job that verifies that the backups for the profile are all intact.
```console
$ sudo systemctl start restic-check@default.timer
$ sudo systemctl enable restic-check@default.timer
````
1. (optional) Setup email on failure as described [here](#8-email-notification-on-failure)
# Step-by-step and manual setup
This is a more detailed explanation than the TL;DR section that will give you more understanding in the setup, and maybe inspire you to develop your own setup based on this one even!
Tip: The steps in this section will instruct you to copy files from this repo to system directories. If you don't want to do this manually, you can use the Makefile:
```console
$ git clone https://github.com/erikw/restic-systemd-automatic-backup.git
$ cd restic-systemd-automatic-backup
$ git clone https://github.com/erikw/restic-systemd-automatic-backup.git && cd $(basename "$_" .git)
$ sudo make install
````
Arch Linux users can install the aur package [restic-systemd-automatic-backup](https://aur.archlinux.org/packages/restic-systemd-automatic-backup/) e.g.:
```console
$ yaourt -S restic-systemd-automatic-backup
````
## 1. Create Backblaze B2 account
First, see this official Backblaze [tutorial](https://help.backblaze.com/hc/en-us/articles/4403944998811-Quickstart-Guide-for-Restic-and-Backblaze-B2-Cloud-Storage) on restic, and follow the instructions ("Create Backblaze account with B2 enabled") there on how to create a new B2 bucket. In general, you'd want a private bucket, without B2 encryption (restic does the encryption client side for us) and without the object lock feature.
First, see this official Backblaze [tutorial](https://help.backblaze.com/hc/en-us/articles/115002880514-How-to-configure-Backblaze-B2-with-Restic-on-Linux) on restic, and follow the instructions ("Create Backblaze account with B2 enabled") there on how to create a new B2 bucket.
Take note of the your account ID, application key and password for the next steps.
Take note of the your account ID and application key for the next steps. It's a good idea to create a separate application key that has access only to the newly created b2 bucket you created.
## 2. Configure your B2 account locally
> **Attention!** Going the manual way requires that most of the following commands are run as root.
Put these files in `/etc/restic/`:
* `b2_env.sh`: Fill this file out with your B2 bucket settings etc. The reason for putting these in a separate file is that it can be used also for you to simply source, when you want to issue some restic commands. For example:
```console
$ source /etc/restic/b2_env.sh
$ restic snapshots # You don't have to supply all parameters like --repo, as they are now in your environment!
````
* `b2_pw.txt`: This file should contain the restic repository password. This is a new password what soon will be used when initializing the new repository. It should be unique to this restic backup repository and is needed for restoring from it. Don't re-use your b2 login password, this should be different.
* `_global.env`: Fill this file out with your global settings including B2 accountID & accountKey. A global exclude list is set here (explained in section below).
* `default.env`: This is the default profile. Fill this out with bucket name, backup paths and retention policy. This file sources `_global.env` and is thus self-contained and can be sourced in the shell when you want to issue some manual restic commands. For example:
```console
$ source /etc/restic/default.env
$ restic snapshots # You don't have to supply all parameters like --repo, as they are now in your environment!
````
* `pw.txt`: This file should contain the restic password used to encrypt the repository. This is a new password what soon will be used when initializing the new repository. It should be unique to this restic backup repository and is needed for restoring from it. Don't re-use your B2 login password, this should be different. For example you can generate a 128 character password (must all be on one line) with:
```console
$ openssl rand -base64 128 | tr -d '\n' > /etc/restic/pw.txt
```
## 3. Initialize remote repo
Now we must initialize the repository on the remote end:
```console
$ source /etc/restic/b2_env.sh
$ sudo -i
$ source /etc/restic/default.env
$ restic init
```
## 4. Script for doing the backup
Put this file in `/usr/local/sbin`:
* `restic_backup.sh`: A script that defines how to run the backup. Edit this file to respect your needs in terms of backup which paths to backup, retention (number of backups to save), etc.
* `restic_backup.sh`: A script that defines how to run the backup. The intention is that you should not need to edit this script yourself, but be able to control everything from the `*.env` profiles.
Copy this file to `/etc/restic/backup_exclude` or `~/.backup_exclude`:
* `.backup_exclude`: A list of file pattern paths to exclude from you backups, files that just occupy storage space, backup-time, network and money.
Restic support exclude files. They list file pattern paths to exclude from you backups, files that just occupy storage space, backup-time, network and money. `restic_backup.sh` allows for a few different exclude files.
* `/etc/restic/backup_exclude` - global exclude list. You can use only this one if your setup is easy. This is set in `_global.env`. If you need a different file for another profile, you can override the envvar `RESTIC_BACKUP_EXCLUDE_FILE` in this profile.
* `.backup_exclude` per backup path. If you have e.g. an USB disk mounted at /mnt/media and this path is included in the `$BACKUP_PATHS`, you can place a file `/mnt/media/.backup_exclude` and it will automatically picked up. The nice thing about this is that the backup paths are self-contained in terms of what they shoud exclude!
## 5. Make first backup & verify
Now see if the backup itself works, by running
## 5. Make first backup
Now see if the backup itself works, by running as root
```console
$ sudo -i
$ source /etc/restic/default.env
$ /usr/local/sbin/restic_backup.sh
$ restic snapshots
````
## 6. Backup automatically; systemd service + timer
## 6. Verify the backup
As the `default.env` is already sourced in your root shell, you can now just list the snapshos
```console
$ sudo -i
$ source /etc/restic/default.env
$ restic snapshots
```
Alternatively you can mount the restic snapshots to a directory set `/mnt/restic`
```console
$ restic mount /mnt/restic
$ ls /mnt/restic
```
## 7. Backup automatically; systemd service + timer
Now we can do the modern version of a cron-job, a systemd service + timer, to run the backup every day!
Put these files in `/etc/systemd/system/`:
* `restic-backup.service`: A service that calls the backup script.
* `restic-backup.timer`: A timer that starts the backup every day.
* `restic-backup@.service`: A service that calls the backup script with the specified profile. The profile is specified
by the value after `@` when running it (see below).
* `restic-backup@.timer`: A timer that starts the former backup every day (same thing about profile here).
* If needed, edit this file to configure [how often](https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events) back up should be made. See the `OnCalendar` key in the file.
Now simply enable the timer with:
```console
$ systemctl start restic-backup.timer
$ systemctl enable restic-backup.timer
$ systemctl start restic-backup@default.timer
$ systemctl enable restic-backup@default.timer
````
☝ **Note**: You can run it with different values instead of `default` if you use multiple profiles.
You can see when your next backup is scheduled to run with
```console
$ systemctl list-timers | grep restic
@@ -108,20 +182,20 @@ $ systemctl status restic-backup
or start a backup manually
```console
$ systemctl start restic-backup
$ systemctl start restic-backup@default
```
You can follow the backup stdout output live as backup is running with:
```console
$ journalctl -f -u restic-backup.service
$ journalctl -f -u restic-backup@default.service
````
(skip `-f` to see all backups that has run)
## 7. Email notification on failure
## 8. Email notification on failure
We want to be aware when the automatic backup fails, so we can fix it. Since my laptop does not run a mail server, I went for a solution to set up my laptop to be able to send emails with [postfix via my Gmail](https://easyengine.io/tutorials/linux/ubuntu-postfix-gmail-smtp/). Follow the instructions over there.
Put this file in `/usr/local/sbin`:
@@ -133,10 +207,17 @@ Put this files in `/etc/systemd/system/`:
As you maybe noticed already before, `restic-backup.service` is configured to start `status-email-user.service` on failure.
## 8. Optional: automated backup checks
## 9. Optional: automated backup checks
Once in a while it can be good to do a health check of the remote repository, to make sure it's not getting corrupt. This can be done with `$ restic check`.
There are some `*-check*`-files in this git repo. Install these in the same way you installed the `*-backup*`-files.
There is companion scripts, service and timer (`*check*`) to restic-backup.sh that checks the restic backup for errors; look in the repo in `etc/systemd/system` and `usr/local/sbin` and copy what you need over to their corresponding locations.
```console
$ sudo -i
$ systemctl start restic-check@default.timer
$ systemctl enable restic-check@default.timer
````
# Cron?
@@ -152,3 +233,13 @@ There is a make target to remove all files (scripts and configs) that were insta
```console
$ sudo make uninstall
```
# Variations
A list of variations of this setup:
* Using `--files-from` [#44](https://github.com/erikw/restic-systemd-automatic-backup/issues/44)
# Development
To not mess up your real installation when changing the `Makefile` simply install to a `$PREFIX` like
```console
$ PREFIX=/tmp/restic-test make install
```

View File

@@ -0,0 +1,20 @@
# Global envionment variables
# These variables are sourced FIRST, and any values inside of *.env files for
# specific configurations will override if also defined there.
# Official instructions on how to setup the restic variables for Backblaze B2 can be found at
# https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2
# The restic repository encryption key
export RESTIC_PASSWORD_FILE="/etc/restic/pw.txt"
# The global restic exclude file
export RESTIC_BACKUP_EXCLUDE_FILE="/etc/restic/backup_exclude"
# Backblaze B2 credentials
export B2_ACCOUNT_ID="<b2-account-id>" # TODO fill with your account info
export B2_ACCOUNT_KEY="<b2-account-key>" # TODO fill with your account info
# How many network connections to set up to B2. Default is 5.
export B2_CONNECTIONS=10

View File

@@ -1,8 +0,0 @@
# B2 credentials.
# Extracted settings so both systemd timers and user can just source this when want to work on my B2 backup.
# See https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html
export RESTIC_REPOSITORY="b2:<b2-repo-name>"
export RESTIC_PASSWORD_FILE="/etc/restic/b2_pw.txt"
export B2_ACCOUNT_ID="<b2-account-id>"
export B2_ACCOUNT_KEY="<b2-account-key>"

View File

@@ -1 +0,0 @@
<b2-password>

View File

@@ -0,0 +1,34 @@
# This is the default profile. Fill it with your desired configuration.
# Additionally, you can create and use more profiles by copying this file.
# This file (and other .env files) has two purposes:
# - being sourced by systemd timers to setup the backup before running restic_backup.sh
# - being sourced in a user's shell to work directly with restic commands e.g.
# $ source /etc/restic/default.env
# $ restic snapshots
# Thus you don't have to provide all the arguments like
# $ restic --repo ... --password-file ...
source /etc/restic/_global.env
# Below envvar will override those in _global.env
export RESTIC_REPOSITORY="b2:<b2-repo-name>" # TODO fill with your repo name
# What to backup (paths our mountpoints) e.g. "/ /boot /home /mnt/media".
# To backup only your home directory, set "/home/your-user"
export BACKUP_PATHS="" # TODO fill conveniently with one or multiple paths
# Example below of how to dynamically add a path that is mounted e.g. external USB disk.
# restic does not fail if a specified path is not mounted, but it's nicer to only add if they are available.
#test -d /mnt/media && BACKUP_PATHS+=" /mnt/media"
# A tag to identify backup snapshots.
export BACKUP_TAG=systemd.timer
# Retention policy - How many backups to keep.
# See https://restic.readthedocs.io/en/stable/060_forget.html?highlight=month#removing-snapshots-according-to-a-policy
export RETENTION_DAYS=14
export RETENTION_WEEKS=16
export RETENTION_MONTHS=18
export RETENTION_YEARS=3

View File

@@ -0,0 +1 @@
<restic-encryption-password>

View File

@@ -1,11 +0,0 @@
[Unit]
Description=Backup with restic to Backblaze B2
OnFailure=status-email-user@%n.service
Requires=nm-unmetered-connection.service
[Service]
Type=simple
Nice=10
ExecStart=/usr/local/sbin/restic_backup.sh
# $HOME or $XDG_CACHE_HOME must be set for restic to find /root/.cache/restic/
Environment="HOME=/root"

View File

@@ -0,0 +1,13 @@
[Unit]
Description=Backup with restic to Backblaze B2
OnFailure=status-email-user@%n.service
Requires=nm-unmetered-connection.service
[Service]
Type=simple
Nice=10
# $HOME or $XDG_CACHE_HOME must be set for restic to find /root/.cache/restic/
Environment="HOME=/root"
# The random sleep (in seconds) is in the case of multiple backup profiles. Many restic instances started at the same time could case high load or network bandwith usage.
# `systemd-cat` allows showing the restic output to the systemd journal
ExecStart=bash -c 'sleep $(shuf -i 0-300 -n 1) && source /etc/restic/%I.env && /usr/local/sbin/restic_backup.sh | systemd-cat'

View File

@@ -7,4 +7,5 @@ Requires=nm-unmetered-connection.service
[Service]
Type=simple
Nice=10
ExecStart=/usr/local/sbin/restic_check.sh
# `systemd-cat` allows showing the restic output to the systemd journal
ExecStart=bash -c 'source /etc/restic/%I.env && /usr/local/sbin/restic_check.sh | systemd-cat'

View File

@@ -1,9 +1,15 @@
#!/usr/bin/env bash
# Make backup my system with restic to Backblaze B2.
# This script is typically run by: /etc/systemd/system/restic-backup.{service,timer}
# Make a backup with restic to Backblaze B2.
#
# This script is typically run (as root user) either like:
# - from restic service/timer: $PREFIX/etc/systemd/system/restic-backup.{service,timer}
# - from a cronjob: $PREFIX/etc/cron.d/restic
# - manually by a user. For it to work, the environment variables must be set in the shell where this script is executed
# $ source $PREFIX/etc/default.env
# $ restic_backup.sh
# Exit on failure, pipe failure
set -e -o pipefail
# Exit on error, unset var, pipe failure
set -euo pipefail
# Clean up lock if we are killed.
# If killed by systemd, like $(systemctl stop restic), then it kills the whole cgroup and all it's subprocesses.
@@ -15,36 +21,20 @@ exit_hook() {
}
trap exit_hook INT TERM
# How many backups to keep.
RETENTION_DAYS=14
RETENTION_WEEKS=16
RETENTION_MONTHS=18
RETENTION_YEARS=3
# What to backup, and what to not
BACKUP_PATHS="/ /boot /home"
[ -d /mnt/media ] && BACKUP_PATHS+=" /mnt/media"
BACKUP_EXCLUDES="--exclude-file /etc/restic/backup_exclude"
for dir in /home/*
do
if [ -f "$dir/.backup_exclude" ]
then
BACKUP_EXCLUDES+=" --exclude-file $dir/.backup_exclude"
# Set up exclude files: global + path-specific ones
# NOTE that restic will fail the backup if not all listed --exclude-files exist. Thus we should only list them if they are really all available.
## Global backup configuration.
exclusion_args="--exclude-file ${RESTIC_BACKUP_EXCLUDE_FILE}"
## Self-contained backup files per backup path. E.g. having an USB disk at /mnt/media in BACKUP_PATHS,
# a file /mnt/media/.backup_exclude will automatically be detected and used:
for backup_path in ${BACKUP_PATHS[@]}; do
if [ -f "$backup_path/.backup_exclude" ]; then
exclusion_args+=" --exclude-file $backup_path/.backup_exclude"
fi
done
BACKUP_TAG=systemd.timer
# Set all environment variables like
# B2_ACCOUNT_ID, B2_ACCOUNT_KEY, RESTIC_REPOSITORY etc.
source /etc/restic/b2_env.sh
# How many network connections to set up to B2. Default is 5.
B2_CONNECTIONS=50
# NOTE start all commands in background and wait for them to finish.
# Reason: bash ignores any signals while child process is executing and thus my trap exit hook is not triggered.
# Reason: bash ignores any signals while child process is executing and thus the trap exit hook is not triggered.
# However if put in subprocesses, wait(1) waits until the process finishes OR signal is received.
# Reference: https://unix.stackexchange.com/questions/146756/forward-sigterm-to-child-in-bash
@@ -61,7 +51,7 @@ restic backup \
--one-file-system \
--tag $BACKUP_TAG \
--option b2.connections=$B2_CONNECTIONS \
$BACKUP_EXCLUDES \
$exclusion_args \
$BACKUP_PATHS &
wait $!
@@ -72,7 +62,7 @@ restic forget \
--verbose \
--tag $BACKUP_TAG \
--option b2.connections=$B2_CONNECTIONS \
--prune \
--prune \
--group-by "paths,tags" \
--keep-daily $RETENTION_DAYS \
--keep-weekly $RETENTION_WEEKS \

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Check my backup with restic to Backblaze B2 for errors.
# This script is typically run by: /etc/systemd/system/restic-check.{service,timer}
# Check the backups made with restic to Backblaze B2 for errors.
# See restic_backup.sh on how this script is run (as it's analogous for this script).
# Exit on failure, pipe failure
set -e -o pipefail
@@ -15,12 +15,6 @@ exit_hook() {
}
trap exit_hook INT TERM
source /etc/restic/b2_env.sh
# How many network connections to set up to B2. Default is 5.
B2_CONNECTIONS=50
# Remove locks from other stale processes to keep the automated backup running.
# NOTE nope, don't unlock like restic_backup.sh. restic_backup.sh should take precedence over this script.
#restic unlock &