2024-08-20 07:09:10 +02:00
# Restic Block {#blocks-restic}
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
Defined in [`/modules/blocks/restic.nix` ](@REPO@/modules/blocks/restic.nix ).
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
This block sets up a backup job using [Restic][restic].
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
[restic]: https://restic.net/
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
## Contract {#blocks-restic-features}
This block implements the [backup ](contracts-backup.html ) contract.
Integration tests are defined in [`/test/blocks/restic.nix` ](@REPO@/test/blocks/restic.nix ).
2023-12-08 20:44:35 +01:00
2023-12-26 08:23:55 +01:00
## Usage {#blocks-backup-usage}
2023-12-09 07:45:58 +01:00
2023-12-26 08:23:55 +01:00
### One folder backed up to mounted hard drives {#blocks-backup-usage-one}
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
The following snippet shows how to configure
the backup of 1 folder to 1 repository.
2024-08-24 07:37:18 +02:00
We assume that the folder is used by the `myservice` service and is owned by a user of the same name.
2023-12-08 20:44:35 +01:00
```nix
2024-08-24 07:37:18 +02:00
shb.restic.instances.myservice = {
2023-12-08 20:44:35 +01:00
enable = true;
2024-08-24 07:37:18 +02:00
user = "myservice";
2024-08-20 07:09:10 +02:00
passphraseFile = "< path / to / passphrase > ";
2023-12-08 20:44:35 +01:00
repositories = [{
2024-08-24 07:37:18 +02:00
path = "/srv/backups/myservice";
2023-12-08 20:44:35 +01:00
timerConfig = {
OnCalendar = "00:00:00";
RandomizedDelaySec = "3h";
};
}];
sourceDirectories = [
"/var/lib/myfolder"
];
retention = {
keep_within = "1d";
keep_hourly = 24;
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
```
2024-08-20 07:09:10 +02:00
### One folder backed up to S3 {#blocks-restic-usage-remote}
2023-12-08 20:44:35 +01:00
Here we will only highlight the differences with the previous configuration.
2024-08-20 07:09:10 +02:00
This assumes you have access to such a remote S3 store, for example by using [Backblaze ](https://www.backblaze.com/ ).
2023-12-08 20:44:35 +01:00
```diff
2024-08-24 07:37:18 +02:00
shb.backup.instances.myservice = {
2023-12-08 20:44:35 +01:00
repositories = [{
- path = "/srv/pool1/backups/myfolder";
+ path = "s3:s3.us-west-000.backblazeb2.com/backups/myfolder";
timerConfig = {
OnCalendar = "00:00:00";
RandomizedDelaySec = "3h";
};
2024-08-20 07:09:10 +02:00
+ extraSecrets = {
2024-08-22 21:48:36 +02:00
+ AWS_ACCESS_KEY_ID.source="< path / to / access_key_id > ";
+ AWS_SECRET_ACCESS_KEY.source="< path / to / secret_access_key > ";
2024-08-20 07:09:10 +02:00
+ };
}];
2023-12-08 20:44:35 +01:00
}
```
2024-08-24 07:37:18 +02:00
### Secrets {#blocks-restic-secrets}
To be secure, the secrets should deployed out of band, otherwise they will be world-readable in the nix store.
To achieve that, I recommend [sops ](usage.html#usage-secrets ) although other methods work great too.
The code to backup to Backblaze with secrets stored in Sops would look like so:
```nix
shb.restic.instances.myfolder.passphraseFile = config.sops.secrets."myservice/backup/passphrase".path;
shb.restic.instances.myfolder.repositories = [
{
path = "s3:s3.us-west-000.backblazeb2.com/< mybucket > ";
secrets = {
AWS_ACCESS_KEY_ID.source = config.sops.secrets."backup/b2/access_key_id".path;
AWS_SECRET_ACCESS_KEY.source = config.sops.secrets."backup/b2/secret_access_key".path;
};
}
];
sops.secrets."myservice/backup/passphrase" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "myservice";
group = "myservice";
};
sops.secrets."backup/b2/access_key_id" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "myservice";
group = "myservice";
};
sops.secrets."backup/b2/secret_access_key" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "myservice";
group = "myservice";
};
```
Pay attention that the owner must be the `myservice` user, the one owning the files to be backed up.
A `secrets` contract is in progress that will allow one to not care about such details.
2024-08-20 07:09:10 +02:00
### Multiple directories to multiple destinations {#blocks-restic-usage-multiple}
2023-12-08 20:44:35 +01:00
2024-08-20 07:09:10 +02:00
The following snippet shows how to configure backup of any number of folders to 3 repositories,
each happening at different times to avoid I/O contention.
2023-12-08 20:44:35 +01:00
We will also make sure to be able to re-use as much as the configuration as possible.
A few assumptions:
- 2 hard drive pools used for backup are mounted respectively on `/srv/pool1` and `/srv/pool2` .
- You have a backblaze account.
2024-08-20 07:09:10 +02:00
First, let's define a variable to hold all the repositories we want to back up to:
2023-12-08 20:44:35 +01:00
```nix
repos = [
{
path = "/srv/pool1/backups";
timerConfig = {
OnCalendar = "00:00:00";
RandomizedDelaySec = "3h";
};
}
{
path = "/srv/pool2/backups";
timerConfig = {
OnCalendar = "08:00:00";
RandomizedDelaySec = "3h";
};
}
{
path = "s3:s3.us-west-000.backblazeb2.com/backups";
timerConfig = {
OnCalendar = "16:00:00";
RandomizedDelaySec = "3h";
};
}
];
```
Compared to the previous examples, we do not include the name of what we will back up in the
repository paths.
Now, let's define a function to create a backup configuration. It will take a list of repositories,
a name identifying the backup and a list of folders to back up.
```nix
backupcfg = repositories: name: sourceDirectories {
enable = true;
backend = "restic";
keySopsFile = ../secrets/backup.yaml;
repositories = builtins.map (r: {
path = "${r.path}/${name}";
inherit (r) timerConfig;
}) repositories;
inherit sourceDirectories;
retention = {
keep_within = "1d";
keep_hourly = 24;
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
environmentFile = true;
};
```
Now, we can define multiple backup jobs to backup different folders:
```nix
shb.backup.instances.myfolder1 = backupcfg repos ["/var/lib/myfolder1"];
shb.backup.instances.myfolder2 = backupcfg repos ["/var/lib/myfolder2"];
```
The difference between the above snippet and putting all the folders into one configuration (shown
below) is the former splits the backups into sub-folders on the repositories.
```nix
shb.backup.instances.all = backupcfg repos ["/var/lib/myfolder1" "/var/lib/myfolder2"];
```
2023-12-09 07:45:58 +01:00
2024-08-20 07:09:10 +02:00
## Demo {#blocks-restic-demo}
2023-12-24 07:50:22 +01:00
2024-01-06 18:43:30 +01:00
[WIP]
2023-12-24 07:50:22 +01:00
2024-08-20 07:09:10 +02:00
## Monitoring {#blocks-restic-monitoring}
2023-12-09 07:45:58 +01:00
[WIP]
2024-08-20 07:09:10 +02:00
## Maintenance {#blocks-restic-maintenance}
2023-12-09 07:45:58 +01:00
2024-08-20 07:09:10 +02:00
One command-line helper is provided per backup instance and repository pair to automatically supply the needed secrets.
In the [multiple directories example ](#blocks-restic-usage-multiple ) above, the following 6 helpers are provided in the `$PATH` :
```bash
restic-myfolder1_srv_pool1_backups
restic-myfolder1_srv_pool2_backups
restic-myfolder1_s3_s3.us-west-000.backblazeb2.com_backups
restic-myfolder2_srv_pool1_backups
restic-myfolder2_srv_pool2_backups
restic-myfolder2_s3_s3.us-west-000.backblazeb2.com_backups
```
Discovering those is easy thanks to tab-completion.
One can then restore a backup with:
```bash
restic-myfolder1_srv_pool1_backups restore latest -t /
```
2023-12-09 07:45:58 +01:00
2024-08-29 09:12:45 +02:00
### Troubleshooting {#blocks-restic-maintenance-troubleshooting}
In case something bad happens with a backup, the [official documentation ](https://restic.readthedocs.io/en/stable/077_troubleshooting.html ) has a lot of tips.
2024-08-20 07:09:10 +02:00
## Options Reference {#blocks-restic-options}
2023-12-09 07:45:58 +01:00
```{=include=} options
2023-12-26 08:23:55 +01:00
id-prefix: blocks-backup-options-
2023-12-09 07:45:58 +01:00
list-id: selfhostblocks-block-backup-options
source: @OPTIONS_JSON @
```