No description
  • Python 98.3%
  • Shell 1.4%
  • Makefile 0.3%
Find a file
bc1bb 89772e5b3e
All checks were successful
Build / Build and analyze (push) Successful in 30s
Actualiser .forgejo/workflows/sonarqube.yml
2026-05-18 01:03:45 +02:00
.forgejo/workflows Actualiser .forgejo/workflows/sonarqube.yml 2026-05-18 01:03:45 +02:00
deploy first commit 2026-05-17 23:38:16 +02:00
docs second commit 2026-05-18 00:55:05 +02:00
src/gardien second commit 2026-05-18 00:55:05 +02:00
tests second commit 2026-05-18 00:55:05 +02:00
.gitignore first commit 2026-05-17 23:38:16 +02:00
CLAUDE.md second commit 2026-05-18 00:55:05 +02:00
LICENSE first commit 2026-05-17 23:38:16 +02:00
Makefile first commit 2026-05-17 23:38:16 +02:00
pyproject.toml first commit 2026-05-17 23:38:16 +02:00
README.md first commit 2026-05-17 23:38:16 +02:00
sonar-project.properties Ajouter sonar-project.properties 2026-05-18 01:01:31 +02:00

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 compose v2 plugin, and git
  • Synology NAS reachable over Netbird, with a backup user, 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 config already done on the host so rclone 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 etc lists 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:

License

MIT — see LICENSE.