- Python 98.3%
- Shell 1.4%
- Makefile 0.3%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| deploy | ||
| docs | ||
| src/gardien | ||
| tests | ||
| .gitignore | ||
| CLAUDE.md | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| sonar-project.properties | ||
gardien
Self-hosted backup orchestrator for Linux servers. Each host runs gardien from a
systemd timer; it discovers what to back up (/etc, /home, /opt/compose/*,
/var/www/*, /etc/letsencrypt), quiesces compose stacks (stop → backup → start, or
hook + dump), and pushes encrypted, deduplicated snapshots via restic to two
destinations: a Synology NAS over SFTP and Infomaniak kDrive via rclone WebDAV. Health
is reported to Uptime Kuma at the end of each run.
5-minute quick start
Bringing gardien up on a new server. Assumes prerequisites — see Prereqs below if any of these are missing:
- Debian/Ubuntu host with systemd,
docker composev2 plugin, andgit - Synology NAS reachable over Netbird, with a
backupuser, an SSH key on the host authorized on the NAS, and the per-host restic + bare-git directories pre-created - Optional but recommended: Infomaniak kDrive Solo/Pro with
rclone configalready done on the host sorclone lsd kdrive:works
1. Copy gardien onto the host (10 s)
sudo install -d -m 0755 /usr/local/src
sudo rsync -a ./ /usr/local/src/gardien/
(Or git clone directly into /usr/local/src/gardien if you keep it in git.)
2. Drop your secrets (30 s)
sudo install -d -m 0750 /etc/backup
sudo bash -c 'openssl rand -base64 32 | tr -d "\n" > /etc/backup/restic.pw'
echo "https://kuma.example.com/api/push/<backup-token>" \
| sudo tee /etc/backup/kuma.url > /dev/null
echo "https://kuma.example.com/api/push/<check-token>" \
| sudo tee /etc/backup/kuma.check.url > /dev/null
sudo chmod 0400 /etc/backup/restic.pw /etc/backup/kuma.url /etc/backup/kuma.check.url
sudo chown root:root /etc/backup/restic.pw /etc/backup/kuma.url /etc/backup/kuma.check.url
Print the restic password and store it offline. Lose this file → lose every backup.
3. Install (90 s)
sudo /usr/local/src/gardien/deploy/install.sh
Idempotent. Installs OS deps (restic, rclone, etckeeper, python3-venv), creates a
venv at /opt/gardien/venv, drops the systemd units, validates the config, and
enables both timers. Re-run after upgrades.
4. Initialize the per-category restic repos (60 s)
sudo bash -c '
set -e
export RESTIC_PASSWORD_FILE=/etc/backup/restic.pw
HOST=$(hostname)
for cat in etc home compose www letsencrypt; do
restic -r "sftp:backup@nas.netbird:/volume1/restic/$HOST/$cat" init
restic -r "rclone:kdrive:restic/$HOST/$cat" init # remove this line if no kDrive
done
'
If you only want NAS for now, set kdrive.enabled: false in
/etc/backup/host.yaml and skip the kDrive init line.
5. Smoke test + first run (60 s)
sudo gardien verify-config # config is valid
sudo gardien plan # see exactly what will run
sudo gardien run --dry-run # exercise the orchestrator without subprocesses
sudo systemctl start gardien-backup # the real thing
sudo journalctl -fu gardien-backup # watch it
When the run finishes:
- Uptime Kuma turns green with a status like
OK 12 jobs / 4.2GB / 18m. sudo jq .overall /var/log/gardien/last.json→"success".sudo gardien snapshots --destination nas --category etclists a snapshot.
From here, the daily timer fires between 02:00 and 04:00 on its own, and the
weekly restic check runs Sunday at 04:00 ± 30 min.
Prereqs (one-time, per environment)
If any of these aren't already true, do these once before the 5-minute flow above:
-
Per-NAS setup (one-time, ~15 min) — backup user, SSH key authorization, pre-created repo + git directories. See docs/31-bootstrapping-nas.md.
-
Per-kDrive setup (one-time, ~10 min) — paid plan check, app password,
rclone config. See docs/32-bootstrapping-kdrive.md. -
Per-host SSH key (one-time, ~1 min per new host):
sudo ssh-keygen -t ed25519 -N "" -f /root/.ssh/id_ed25519_backup -C "gardien@$(hostname)" sudo cat /root/.ssh/id_ed25519_backup.pub # paste onto the NAS authorized_keys sudo ssh nas.netbird true # silently succeeds = ready
Why
Most backup tools are either "rsync to one place and pray" or a sprawling enterprise
appliance. This project sits in the middle: a small, opinionated Python orchestrator
that treats restic as the data plane and adds the parts that aren't about moving
bytes — discovery, quiesce, signal-safe rollback, retention, reporting.
Status
Alpha. Feature-complete per the architecture plan; lint, type-check, and tests are green. Awaiting first-host pilot.
Documentation
See docs/00-index.md. Each topic lives in its own short file so Claude Code (or a human) can load only what's needed.
Quick links:
- Deploying to a new server — the longer version of the 5-minute flow above, with verification and rollback notes.
- Synology NAS setup
- Infomaniak kDrive setup
- Writing per-stack hooks
- Restoring data
- Troubleshooting
License
MIT — see LICENSE.