Files
vh 2be296ffa0 homepage: function-first layout + fleet label sweep
Reorganize the gethomepage dashboard from site-based (PFI-ANA, ESH, NH3)
to function-first grouping (Monitoring, AI Systems, Apps, Media, Games,
Infra-<site>, Service Networking). Canonical config now tracked in
configs/homepage/ with Plex/Jellyfin widget keys moved to env
substitution.

Label sweep across fleet compose files:
  - beszel, dozzle, backrest -> Monitoring
  - rest-server-ana -> Service Networking

Healthcheck fixes (previous wget/curl paths broke on distroless +
--private-repos 401):
  - beszel hub:    /beszel health --url ...
  - beszel agent:  /agent health (newly added)
  - rest-server:   nc -z localhost 8000 (TCP probe)

Group name originally "Wiring / Plumbing" collapsed to single-word group
on homepage's parser; renamed to "Service Networking" everywhere.
2026-04-20 22:14:00 -07:00
..

backrest

Web UI over restic repositories. Runs once, on ana-docker, and points at every per-host restic repo on both site-local S3 endpoints to give a single pane of glass for snapshot history, restores, and alerts.

Server: ana-docker Port: http://10.250.50.70:9898

Role in the fleet

  • Actual backups are run by per-host systemd timers calling restic. Each host writes to its site-local rest-server (ana-docker for Anaheim hosts, Synology for NH3).
  • This container does not run backups by default — it's a viewer/manager pointed at existing repos. (Backrest can be the scheduler instead of systemd timers; we're keeping the scheduler on the host for simplicity.)
  • Because it only needs to talk to S3 endpoints (not host filesystems), no bind mounts of host paths are required.

Deploy

# On ana-docker:
sudo mkdir -p /opt/docker/compose/backrest
sudo chown $USER /opt/docker/compose/backrest
cd /opt/docker/compose/backrest

# scp compose.yaml + .env.example from this workspace, then:
cp .env.example .env
# edit .env if you want a different port or TZ

docker compose config
docker compose up -d
docker compose logs -f

Open http://10.250.50.70:9898 and set the admin credentials on first load.

First-time configuration (in the UI)

For each per-host repo (to be added once the restic pipeline is running):

  1. Add Repository → fill in:
    • ID: e.g. ana-docker, ana-ml2, nh3-docker, esh-docker-vm
    • URI: s3:https://10.250.50.50:4521/pfi-backups/ana/ana-docker/ (or the nh3 endpoint, depending on host)
    • Password: the restic passphrase for that host
    • Env: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY for the S3 endpoint
  2. (Do not create a plan unless you want Backrest to drive the schedule — leave schedules to the systemd timers on each host.)
  3. Verify: the repo should list snapshots pulled by the host's systemd timer within a few minutes.

Backup scope, when wired up

  • ana-docker, ana-ml2, esh-docker-vm → Anaheim rest-server on ana-docker (:8000), data on NFS mount backed by the Debian file server at 10.250.50.50
  • nh3-docker → NH3 rest-server on the Synology (10.100.50.50:8000), data on local Btrfs
  • Cross-site rsync will make each NAS hold the other site's data, so you can restore either host from either side if one NAS is down.

Scaling knobs

  • Upgrade: docker compose pull && docker compose up -d.
  • Backup of Backrest itself: its config/DB lives in the backrest_config and backrest_data volumes — include those in ana-docker's restic plan so recreating the UI doesn't mean re-entering every repo.

Why not offen/docker-volume-backup?

Two instances on esh-docker-vm (paperless-ngx, pgadmin) currently use the offen/docker-volume-backup sidecar pattern. Those will be retired once restic is in place:

  • No encryption — backups sit in the clear on NFS.
  • No dedup — every run writes a full tarball; storage grows linearly.
  • Per-stack config — every new service needs its own sidecar wiring.
  • No cross-host index — restores require knowing which tarball lives where.

Restic + Backrest solves all four at the cost of one extra binary per host. Leave the sidecars running until the restic plan is verified, then remove them in a scheduled change.