README.md

  1## Example setup
  2
  3[`keld/`](./keld/) is example content for `~/.config/keld`. It contains a config and some env files for the systemd stuff. [`systemd/user/`](./systemd/user/) contains that systemd stuff. Backup runs daily, verify runs monthly, both read from the env files to ping healthchecks.io and let you know whether your backups failed. Both also use mise to install/execute runitor (for healthchecks) and keld.
  4
  5[`config_long.toml`](./keld/config_long.toml) is more exhaustive.
  6
  7### 1. Copy the configs
  8
  9```bash
 10mkdir -p ~/.config/keld/timers
 11cp -r examples/keld/* ~/.config/keld/
 12```
 13
 14### 2. Edit
 15
 16Open `~/.config/keld/config.toml` and customize it for your backups:
 17
 18- Define your presets (e.g., `media@hetzner_media`, `docs@b2_docs`)
 19- Set your repository URLs
 20- Configure environment variables for authentication
 21- Set backup sources via `_arguments`
 22
 23Backup presets can also define shell hooks:
 24
 25```toml
 26["media@".backup]
 27_arguments = ["/home/user/Music/Final"]
 28_pre_hooks = ["echo preparing media backup"]
 29_post_hooks = ["echo backup finished with $KELD_RESTIC_STATUS"]
 30```
 31
 32`_pre_hooks` run before `restic backup`. If a pre-hook fails, restic is not
 33started and post-hooks do not run. `_post_hooks` run after restic is attempted,
 34even when restic fails. Post-hooks receive `KELD_RESTIC_STATUS` and, when restic
 35started, `KELD_RESTIC_EXIT_CODE`. Use `keld --show-command --preset <preset>
 36backup` to preview configured hooks without running them.
 37
 38Keld status names are based on [restic's documented exit
 39codes](https://restic.readthedocs.io/en/stable/075_scripting.html#exit-codes),
 40with one extra status for restic start failures:
 41
 42| Restic exit code | `KELD_RESTIC_STATUS` | Meaning |
 43| ---------------- | -------------------- | ------- |
 44| 0                | `success`            | Restic completed successfully. |
 45| 1                | `fatal`              | Restic failed; see restic output for details. |
 46| 2                | `runtime_error`      | Go runtime error. |
 47| 3                | `partial`            | `backup` could not read some source data. |
 48| 10               | `repository_missing` | Repository does not exist. |
 49| 11               | `locked`             | Restic failed to lock the repository. |
 50| 12               | `wrong_password`     | Repository password was wrong. |
 51| 130              | `interrupted`        | Restic was interrupted. |
 52| 143              | `terminated`         | Restic was terminated by SIGTERM. |
 53| other non-zero   | `unknown_failure`    | Unknown restic failure; treat as failed. |
 54| restic not started | `start_failed`     | Keld could not start the restic process. |
 55
 56Repeat this to add backups later.
 57
 58### 3. Set up healthchecks.io (optional)
 59
 60Create two checks on [healthchecks.io](https://healthchecks.io) for each backup:
 61
 62- One for the backup job
 63- One for the verify job
 64
 65Create env files in `~/.config/keld/timers/`:
 66
 67```bash
 68# ~/.config/keld/timers/mybackup@myrepo.env
 69CHECK_UUID=your-backup-check-uuid-here
 70
 71# ~/.config/keld/timers/mybackup@myrepo-verify.env
 72CHECK_UUID=your-verify-check-uuid-here
 73```
 74
 75Repeat this to add backups later.
 76
 77### 4. Install the systemd units
 78
 79```bash
 80mkdir -p ~/.config/systemd/user
 81cp examples/systemd/user/* ~/.config/systemd/user/
 82```
 83
 84### 5. Enable and start the timers
 85
 86For each backup preset you defined (e.g., `media@hetzner_media`):
 87
 88```bash
 89# Escape the @ symbol for systemd instance names
 90systemctl --user enable keld-backup@media@hetzner_media.timer
 91systemctl --user start keld-backup@media@hetzner_media.timer
 92
 93systemctl --user enable keld-verify@media@hetzner_media.timer
 94systemctl --user start keld-verify@media@hetzner_media.timer
 95```
 96
 97Repeat this to add backups later.
 98
 99### 6. Verify everything is working
100
101```bash
102# List active timers
103systemctl --user list-timers
104
105# Check service status
106systemctl --user status keld-backup@media@hetzner_media.service
107
108# Test a dry run
109keld --show-command --preset media@hetzner_media backup
110```
111
112Repeat this to add backups later.