Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
956ebfb29b | ||
|
|
d34fbfc9d3 | ||
|
|
213fb95bdc | ||
|
|
ae228186eb | ||
|
|
3460e9accf | ||
|
|
6689b1508f | ||
|
|
77c095c12a | ||
|
|
47ac748a27 | ||
|
|
28dece45ae | ||
|
|
d9459cb048 | ||
|
|
b8716ad377 | ||
|
|
b261235ba5 | ||
|
|
88f2dc9eca | ||
|
|
16e3cb2df5 | ||
|
|
9e0735ac01 | ||
|
|
6e24a66a1c | ||
|
|
265ff699f8 | ||
|
|
bcd4a02e82 | ||
|
|
e5502b0655 | ||
|
|
be6ab0c37a | ||
|
|
c7d702a1ed | ||
|
|
fa220b3a91 | ||
|
|
e943e94f05 | ||
|
|
71f1bd8e61 | ||
|
|
2629c77192 | ||
|
|
4bb30eee90 | ||
|
|
ac678acb46 | ||
|
|
429ee40220 | ||
|
|
be5c07bd0f | ||
|
|
197b4b7064 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
b2_env.sh
|
||||
b2_pw.txt
|
||||
/etc/restic/b2_pw.txt
|
||||
/etc/restic/b2_env.sh
|
||||
|
||||
22
CHANGELOG.md
Normal file
22
CHANGELOG.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.0] - 2021-12-02
|
||||
It's time to call this a proper major version!
|
||||
|
||||
### Added
|
||||
- `uninstall` target for `Makefile`
|
||||
- Add `--prune` to `restic-forget`
|
||||
- README badges and updates.
|
||||
|
||||
### Fixed
|
||||
- `backup_exclude` destination
|
||||
- Conflicts for restic-check service
|
||||
|
||||
## [0.1.0] - 2019-07-23
|
||||
- First tagged version.
|
||||
15
Makefile
15
Makefile
@@ -1,5 +1,5 @@
|
||||
# Not file targets.
|
||||
.PHONY: help install install-scripts install-conf install-systemd
|
||||
.PHONY: help install install-scripts install-conf install-systemd uninstall
|
||||
|
||||
### Macros ###
|
||||
SRCS_SCRIPTS = $(filter-out %cron_mail, $(wildcard usr/local/sbin/*))
|
||||
@@ -12,6 +12,8 @@ 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
|
||||
|
||||
### Targets ###
|
||||
# target: all - Default target.
|
||||
@@ -31,10 +33,10 @@ install-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
|
||||
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
|
||||
install -m 0600 etc/restic/b2_pw.txt.template /etc/restic/b2_pw.txt
|
||||
|
||||
# target: install-conf - Install restic configuration files.
|
||||
# will create these files locally only if they don't already exist
|
||||
@@ -46,3 +48,10 @@ install-conf: | etc/restic/b2_env.sh etc/restic/b2_pw.txt
|
||||
install-systemd:
|
||||
install -d $(DEST_SYSTEMD)
|
||||
install -m 0644 $(SRCS_SYSTEMD) $(DEST_SYSTEMD)
|
||||
|
||||
# target: uninstall - Uninstall files from the install targets
|
||||
uninstall:
|
||||
@for file in $(INSTALLED_FILES); do \
|
||||
echo $(RM) $$file; \
|
||||
$(RM) $$file; \
|
||||
done
|
||||
|
||||
1
OSSMETADATA
Normal file
1
OSSMETADATA
Normal file
@@ -0,0 +1 @@
|
||||
osslifecycle=active
|
||||
75
README.md
75
README.md
@@ -1,6 +1,22 @@
|
||||
# Automatic restic backups using systemd services and timers
|
||||
[](#)
|
||||
[](#)
|
||||
<br>
|
||||
[](#)
|
||||
[](https://github.com/erikw/restic-systemd-automatic-backup/issues)
|
||||
[](https://github.com/erikw/restic-systemd-automatic-backup/issues?q=is%3Aissue+is%3Aclosed)
|
||||
[](https://github.com/erikw/restic-systemd-automatic-backup/pulls?q=is%3Apr+is%3Aclosed)
|
||||
[](LICENSE.txt)
|
||||
[](https://github.com/Netflix/osstracker)
|
||||
[](https://github.com/erikw/restic-systemd-automatic-backup/tags)
|
||||
<br>
|
||||
|
||||
## Restic
|
||||
[](https://github.com/erikw/restic-systemd-automatic-backup/graphs/contributors) including these top contributors:
|
||||
<a href = "https://github.com/erikw/restic-systemd-automatic-backup/graphs/contributors">
|
||||
<img src = "https://contrib.rocks/image?repo=erikw/restic-systemd-automatic-backup&max=24"/>
|
||||
</a>
|
||||
|
||||
# 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!
|
||||
|
||||
@@ -11,58 +27,59 @@ Here follows a step-by step tutorial on how to set it up, with my sample script
|
||||
|
||||
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`
|
||||
|
||||
## Set up
|
||||
# Set up
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ git clone https://github.com/erikw/restic-systemd-automatic-backup.git
|
||||
$ cd restic-systemd-automatic-backup
|
||||
$ sudo make install
|
||||
````
|
||||
|
||||
### 1. Create Backblaze B2 account
|
||||
## 1. Create Backblaze B2 account
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
### 2. Configure your B2 account locally
|
||||
## 2. Configure your B2 account locally
|
||||
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:
|
||||
```bash
|
||||
```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`: Put your B2 password in this file.
|
||||
* `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.
|
||||
|
||||
### 3. Initialize remote repo
|
||||
## 3. Initialize remote repo
|
||||
Now we must initialize the repository on the remote end:
|
||||
```bash
|
||||
source /etc/restic/b2_env.sh
|
||||
restic init
|
||||
```console
|
||||
$ source /etc/restic/b2_env.sh
|
||||
$ restic init
|
||||
```
|
||||
|
||||
### 4. Script for doing the backup
|
||||
## 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.
|
||||
|
||||
Put this file in `/`:
|
||||
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.
|
||||
|
||||
|
||||
### 5. Make first backup & verify
|
||||
## 5. Make first backup & verify
|
||||
Now see if the backup itself works, by running
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ /usr/local/sbin/restic_backup.sh
|
||||
$ restic snapshots
|
||||
````
|
||||
|
||||
### 6. Backup automatically; systemd service + timer
|
||||
## 6. 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!
|
||||
|
||||
|
||||
@@ -72,31 +89,31 @@ Put these files in `/etc/systemd/system/`:
|
||||
|
||||
|
||||
Now simply enable the timer with:
|
||||
```bash
|
||||
```console
|
||||
$ systemctl start restic-backup.timer
|
||||
$ systemctl enable restic-backup.timer
|
||||
````
|
||||
|
||||
You can see when your next backup is scheduled to run with
|
||||
```bash
|
||||
```console
|
||||
$ systemctl list-timers | grep restic
|
||||
```
|
||||
|
||||
and see the status of a currently running backup with
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ systemctl status restic-backup
|
||||
```
|
||||
|
||||
or start a backup manually
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ systemctl start restic-backup
|
||||
```
|
||||
|
||||
You can follow the backup stdout output live as backup is running with:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ journalctl -f -u restic-backup.service
|
||||
````
|
||||
|
||||
@@ -104,7 +121,7 @@ $ journalctl -f -u restic-backup.service
|
||||
|
||||
|
||||
|
||||
### 7. Email notification on failure
|
||||
## 7. 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`:
|
||||
@@ -116,14 +133,22 @@ 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
|
||||
## 8. 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.
|
||||
|
||||
|
||||
## Cron?
|
||||
# Cron?
|
||||
If you want to run an all-classic cron job instead, do like this:
|
||||
|
||||
* `etc/cron.d/restic`: Depending on your system's cron, put this in `/etc/cron.d/` or similar, or copy the contents to $(sudo crontab -e). The format of this file is tested under FreeBSD, and might need adaptions depending on your cron.
|
||||
* `usr/local/sbin/cron_mail`: A wrapper for running cron jobs, that sends output of the job as an email using the mail(1) command.
|
||||
|
||||
# Uninstall
|
||||
|
||||
There is a make target to remove all files (scripts and configs) that were installed by `sudo make install`. Just run:
|
||||
|
||||
```console
|
||||
$ sudo make uninstall
|
||||
```
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=Check restic backup Backblaze B2 for errors
|
||||
OnFailure=status-email-user@%n.service
|
||||
Conflicts=restic.service
|
||||
Conflicts=restic-backup.service
|
||||
Requires=nm-unmetered-connection.service
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -65,12 +65,14 @@ restic backup \
|
||||
$BACKUP_PATHS &
|
||||
wait $!
|
||||
|
||||
# Dereference old backups.
|
||||
# Dereference and delete/prune old backups.
|
||||
# See restic-forget(1) or http://restic.readthedocs.io/en/latest/060_forget.html
|
||||
# --group-by only the tag and path, and not by hostname. This is because I create a B2 Bucket per host, and if this hostname accidentially change some time, there would now be multiple backup sets.
|
||||
restic forget \
|
||||
--verbose \
|
||||
--tag $BACKUP_TAG \
|
||||
--option b2.connections=$B2_CONNECTIONS \
|
||||
--prune \
|
||||
--group-by "paths,tags" \
|
||||
--keep-daily $RETENTION_DAYS \
|
||||
--keep-weekly $RETENTION_WEEKS \
|
||||
@@ -78,13 +80,6 @@ restic forget \
|
||||
--keep-yearly $RETENTION_YEARS &
|
||||
wait $!
|
||||
|
||||
# Remove old data not linked anymore.
|
||||
# See restic-prune(1) or http://restic.readthedocs.io/en/latest/060_forget.html
|
||||
restic prune \
|
||||
--option b2.connections=$B2_CONNECTIONS \
|
||||
--verbose &
|
||||
wait $!
|
||||
|
||||
# Check repository for errors.
|
||||
# NOTE this takes much time (and data transfer from remote repo?), do this in a separate systemd.timer which is run less often.
|
||||
#restic check &
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Send email notification from systemd.
|
||||
# Source: https://serverfault.com/questions/876233/how-to-send-an-email-if-a-systemd-service-is-restarted
|
||||
# Source: https://wiki.archlinux.org/index.php/Systemd/Timers#MAILTO
|
||||
# Usage: systemd-email <recipinent-email> <failed-systemd-unit-name>
|
||||
# Usage: systemd-email <recipient-email> <failed-systemd-unit-name>
|
||||
|
||||
|
||||
# According to
|
||||
@@ -47,11 +47,11 @@ if ! waited_long_enough; then
|
||||
fi
|
||||
|
||||
|
||||
recipinent=$1
|
||||
recipient=$1
|
||||
system_unit=$2
|
||||
|
||||
sendmail -t <<ERRMAIL
|
||||
To: $recipinent
|
||||
To: $recipient
|
||||
From: systemd <root@$HOSTNAME>
|
||||
Subject: [systemd-email] ${system_unit}
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reference in New Issue
Block a user