/
/
/
Ansible role that can run restic backups and push it to a remote storage server.
1# Backup
2
3Restic backups for every host in `[backup_clients]`, run by `backup.yml` and
4scheduled weekly in Semaphore. One run backs up all clients, then maintains the
5repository once and reports to Home Assistant.
6
7## What is backed up
8
9| Source | How | Snapshot tags |
10|---|---|---|
11| Every `/docker/<service>` | Running containers are stopped, backed up, and **exactly those** are started again (`always`, also on failure). Stacks that are down stay down. | `<service>`, `docker` |
12| `backup_data_paths` | Hot, from local disk. Only the path's own excludes apply. | `<name>`, `data` |
13| Home Assistant | Full backup via `ha backups new`, then the backup directory | `homeassistant`, `appliance` |
14| OPNsense | `config.xml` via the API (needs *Diagnostics: Configuration History*) | `opnsense`, `appliance` |
15
16New `/docker` directories are included automatically. Skipped: `glances`, `gdu`,
17`restic-server`, `appliance-backups` (+ `backup_host_skip_services`).
18
19## Exclusions
20
211. **Global** (`backup_global_excludes`, `/docker` only): `cache`, `.cache`, `logs`,
22 `*.log`, `MediaCover`, `.git`, plus `--exclude-caches` and any directory with a
23 `.nobackup` file.
242. **Per service** (`backup_service_excludes`, host_vars), relative to `/docker/<svc>`,
25 e.g. `llm-stack: ["ollama/data"]`.
263. **Extra paths** that belong to a service (`backup_service_extra_paths`), e.g. a
27 database in a named Docker volume, are snapshotted with it while it is stopped.
28
29## Key Parameters
30
31| Variable | Default | Description |
32|----------|---------|-------------|
33| `backup_restic_version` | `0.19.1` | Pinned client, installed from the release with checksum |
34| `restic_backup_repo` / `restic_backup_password` | (vault) | Repository URL and password |
35| `backup_retention_args` | `--keep-weekly 8 --keep-monthly 12` | `forget` policy, grouped by host + tags |
36| `backup_check_read_subset` | `5%` | Share of pack data read back by `restic check` per run |
37| `backup_offsite_repo` | `""` | Second repository; when set, `restic copy` runs after each backup |
38| `backup_hot_services` | `[]` | Services backed up without stopping them |
39| `backup_report_enabled` | `true` | Publish `sensor.homelab_backup_*` to Home Assistant |
40
41## Workflow
42
431. Install the pinned restic, check the repository (init only if it does not exist)
442. Per host: back up each service, data path and appliance, recording each outcome
453. Once, on the repository host: `forget --prune`, `check --read-data-subset`,
46 optional off-site `copy`
474. Report to Home Assistant through `mqtt.publish` (retained MQTT discovery sensors)
485. Fail the run if any item failed, a client was missed, or `check` failed
49
50## Home Assistant sensors
51
52| Entity | State | Attributes |
53|---|---|---|
54| `sensor.homelab_backup_status` | `ok` / `failed` | the full report: per-service last snapshot, age, count, oldest, size; failures; missed hosts |
55| `sensor.homelab_backup_last_run` | timestamp | |
56| `sensor.homelab_backup_repo_size` | GB | |
57
58## Restore
59
60```sh
61# A /docker service, from its latest snapshot on that host
62ansible-playbook backup.yml -e backup_mode=restore -e backup_services=mealie --limit runner
63```
64
65Data paths and appliances are restored by hand:
66
67```sh
68restic snapshots --tag pictures # find the snapshot
69restic restore <id> --target / --include /mnt/rstorage/media/pictures
70```
71
72Home Assistant: restore the `restic-<date>` backup file from the snapshot into
73`/var/lib/homeassistant/backup`, then restore it in HA. OPNsense: upload the
74`config-<date>.xml` under *System â Configuration â Backups*.
75