Example setup
keld/ is example content for ~/.config/keld. It contains a config and some env files for the systemd stuff. 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.
config_long.toml is more exhaustive.
1. Copy the configs
mkdir -p ~/.config/keld/timers
cp -r examples/keld/* ~/.config/keld/
2. Edit
Open ~/.config/keld/config.toml and customize it for your backups:
- Define your presets (e.g.,
media@hetzner_media,docs@b2_docs) - Set your repository URLs
- Configure environment variables for authentication
- Set backup sources via
_arguments
Backup presets can also define shell hooks:
["media@".backup]
_arguments = ["/home/user/Music/Final"]
_pre_hooks = ["echo preparing media backup"]
_post_hooks = ["echo backup finished with $KELD_RESTIC_STATUS"]
_pre_hooks run before restic backup. If a pre-hook fails, restic is not
started and post-hooks do not run. _post_hooks run after restic is attempted,
even when restic fails. Post-hooks receive KELD_RESTIC_STATUS and, when restic
started, KELD_RESTIC_EXIT_CODE. Use keld --show-command --preset <preset> backup to preview configured hooks without running them.
Keld status names are based on restic's documented exit codes, with one extra status for restic start failures:
| Restic exit code | KELD_RESTIC_STATUS |
Meaning |
|---|---|---|
| 0 | success |
Restic completed successfully. |
| 1 | fatal |
Restic failed; see restic output for details. |
| 2 | runtime_error |
Go runtime error. |
| 3 | partial |
backup could not read some source data. |
| 10 | repository_missing |
Repository does not exist. |
| 11 | locked |
Restic failed to lock the repository. |
| 12 | wrong_password |
Repository password was wrong. |
| 130 | interrupted |
Restic was interrupted. |
| 143 | terminated |
Restic was terminated by SIGTERM. |
| other non-zero | unknown_failure |
Unknown restic failure; treat as failed. |
| restic not started | start_failed |
Keld could not start the restic process. |
Repeat this to add backups later.
3. Set up healthchecks.io (optional)
Create two checks on healthchecks.io for each backup:
- One for the backup job
- One for the verify job
Create env files in ~/.config/keld/timers/:
# ~/.config/keld/timers/mybackup@myrepo.env
CHECK_UUID=your-backup-check-uuid-here
# ~/.config/keld/timers/mybackup@myrepo-verify.env
CHECK_UUID=your-verify-check-uuid-here
Repeat this to add backups later.
4. Install the systemd units
mkdir -p ~/.config/systemd/user
cp examples/systemd/user/* ~/.config/systemd/user/
5. Enable and start the timers
For each backup preset you defined (e.g., media@hetzner_media):
# Escape the @ symbol for systemd instance names
systemctl --user enable keld-backup@media@hetzner_media.timer
systemctl --user start keld-backup@media@hetzner_media.timer
systemctl --user enable keld-verify@media@hetzner_media.timer
systemctl --user start keld-verify@media@hetzner_media.timer
Repeat this to add backups later.
6. Verify everything is working
# List active timers
systemctl --user list-timers
# Check service status
systemctl --user status keld-backup@media@hetzner_media.service
# Test a dry run
keld --show-command --preset media@hetzner_media backup
Repeat this to add backups later.