Stage 1/hosts/dev/sources · default group present (fresh-ish host)
Tweaks · default only multi-group
restic-manager
v0.2.0-alpha
steve@dcglab
Dashboard/dev/sources

# dev

homelab
linux/amd64 · online · last heartbeat 3s ago
Snapshots 14
Sources 3
Schedules 2
Repo
Jobs
Settings

Each source group is a named bundle of paths plus the rule for how long its snapshots stick around. Schedules point at one or more groups — one restic backup runs per group, tagged by name so forget can apply retention cleanly.

default
2 includes · 1 exclude · keep last 7, daily 14, weekly 4
used by 1 schedule · last run succeeded · 12m ago · 52 snapshots
databases
2 includes · 1 exclude · keep last 7, hourly 24, daily 14, weekly 6, monthly 6
used by 2 schedules · last run succeeded · 2h ago · 68 snapshots
photos keep-hourly · no sub-daily schedule
1 include · 0 excludes · keep hourly 24, monthly 24
used by 1 schedule · last run succeeded · 6h ago · 7 snapshots
default empty
0 includes · 0 excludes · no retention set — keep everything
used by 0 schedules · never run
default can't be deleted while it's the only group on the host. · Run-now on a row dispatches one immediate backup using that group's paths and tag.
Stage 2/hosts/dev/sources/01KQ.../edit · editing databases
restic-manager
steve@dcglab
Dashboard/dev/sources/databases

# Edit source group · databases

What this group covers and how long its snapshots are worth keeping. Snapshots produced for this group carry the tag databases — change the name with care: existing snapshots keep the old tag and won't get retained by a renamed group's policy.

### Identity

Name
Used as the snapshot tag. Lowercase, no spaces; matches what restic forget --tag sees.

### Paths

Includes · one path per line /var/lib/postgresql /etc/postgresql
What restic backup walks. Agent runs as root with CAP_DAC_READ_SEARCH, so any readable path is fair game.
Excludes · optional, one pattern per line **/pg_wal/** *.tmp
Passed straight through as --exclude args.

### Retention applied nightly · all blank = keep everything

⚠
keep-hourly is set, but no schedule pointing at this group fires more often than once a day. The hourly bucket will never have snapshots to retain — restic forget treats the value as a no-op. Either drop keep-hourly or add a sub-daily schedule. Finest schedule interval: 24h · keep-hourly requires < 1h.
Keep last
Hourly
Daily
Weekly
Monthly
Yearly
Translates to restic forget --tag databases --keep-last 7 --keep-hourly 24 --keep-daily 14 --keep-weekly 6 --keep-monthly 6. Forget runs nightly per host (cadence on the Repo tab); pruning the freed data is admin-only and weekly.

### Retry on offline cron-fired runs only

Max attempts
Initial backoff (sec)
Each retry doubles the wait. Manual run-now ignores this — it just fails immediately if the agent is offline, since the operator's eyes are on the page.
How this fits

1. 1
   Save here
   Bumps the host's schedule version; the agent picks up the new paths/retention on its next push (within seconds when online).
2. 2
   Schedules pointing here change behaviour
   Any schedule that includes databases in its source picker now backs up the new paths next time it fires. Currently 1 schedule references this group.
3. 3
   Retention applies on the next nightly forget
   Existing tagged snapshots get re-evaluated against the new keep-* rules. Untagged or differently-tagged snapshots are untouched.
4. 4
   Run-now from the Sources list
   Want to test? Save, go back to Sources, hit Run-now on this row — runs one immediate backup with the new config, no waiting for cron.

Heads up

Renaming a group doesn't retag its existing snapshots. If you rename databases to postgres, old snapshots with the databases tag will stop being managed by this group's retention rules — they'll fall through to "untagged forever-keep" until you manually re-tag or delete them.

Stage 3/hosts/dev/schedules · simplified — when only
restic-manager
steve@dcglab
Dashboard/dev/schedules

# dev

schedule version 3 · agent in sync
Snapshots
Sources
Schedules 3
Repo
Jobs
Settings

A schedule is just a cron expression pointing at one or more source groups. When it fires, the agent runs a separate restic backup per chosen group — independent jobs, independent snapshots, independent retention. Failure of one group doesn't fail the others.

Status
Cron
Sources
enabled
@hourly
databases
enabled
0 3 * * *
default photos databases
paused
0 3 * * 0
photos
— New schedule form —

### When

Cron expression
0 3 * * * @hourly 0 */6 * * * 0 3 * * 0 0 3 1 * *
Standard 5-field cron with descriptors. Server validates with the same parser the agent uses to fire — what saves here is what runs.

### What — pick one or more source groups

default 2 paths · keep last 7, daily 14
databases 2 paths · keep last 7, daily 14, weekly 6
photos 1 path · keep monthly 24
Each picked group runs as a separate restic backup with its own tag — its own snapshot, its own retention. Pick multiple to fire them all on the same cron tick.

### Status

Enabled — uncheck to keep the row but stop firing.
No paths, no retention, no kind

That stuff lives on source groups now. A schedule's only job is to be the cron expression and to point at the groups it should fire. This keeps the form short and means schedules and sources can change independently — change a group's retention, every schedule that points at it inherits the change without further edits.

Forget / prune / check are not schedule kinds anymore. They run on host-level cadences from the Repo tab with sensible defaults.

If the agent is offline at fire time

Server retries per the group's retry policy (max attempts + exponential backoff). If the command reaches the agent and the backup fails for non-network reasons (path missing, permission denied), no retry — just a failed job in the log.

Stage 4/hosts/dev/repo · connection · maintenance · danger zone
restic-manager
steve@dcglab
Dashboard/dev/repo

# dev

Snapshots
Sources
Schedules
Repo
Jobs
Settings

## Connection

Repo URL
rest:http://192.168.0.99:8000/dev/
Username
dev
Password
•••••••••••••••• stored, never displayed
Cert pin
— HTTP-only behind reverse proxy

## Bandwidth · host-wide

Upload limit · KB/s · blank = no cap
Download limit · KB/s · blank = no cap
Applies to every backup, restore, and prune job for this host. Configure per-host because the network constraint usually is the host (its uplink). Per-source is rare enough we don't surface it.

## Maintenance · auto-managed

forget
Cadence
daily · 03:00
Last run
succeeded · 12h ago
Per source group, using each group's retention policy.
enabled
prune
Cadence
weekly · Sun 04:00
Last run
succeeded · 4d ago
Reclaims storage made dead by forget. Heavy — runs weekly only.
enabled
check
Cadence
monthly · 1st 05:00
Last run
succeeded · 22d ago
--read-data-subset 5% · spreads full coverage over ~20 months.
enabled

## Danger zone

Re-initialise repo

Tries to DELETE the rest-server's copy of this repo, then runs restic init against the empty path. Most rest-server setups run with --append-only and refuse the DELETE — in that case the page shows guided cleanup steps instead of attempting anything destructive.

All snapshots are lost; this host's schedule version stays the same and the agent's secrets.enc is reused.

## Storage

Repo size
412 GB
dedup ratio 6.4×
Snapshots
127
across 3 source groups
Last check
succeeded
22 days ago
Lock state
unlocked
no held locks

## Snapshots by source

default 52 snapshots databases 68 snapshots photos 7 snapshots
Untagged snapshots

Any snapshot not tagged with one of this host's source groups is left alone — forget never touches it. Useful if someone runs restic backup outside restic-manager; nothing here will silently delete those.