# restic-manager

Self-hosted, browser-based, single-pane-of-glass for managing
[restic](https://restic.net) backups across a fleet of Linux and
Windows endpoints.

> **Status:** pre-1.0, feature-complete for the original use
> case. Phases 0–4 + 6 are landed (MVP, scheduling, restore,
> RBAC + OIDC, observability); Phase 5 (OSS readiness — docs site,
> contributor onboarding, end-to-end CI) is in flight. See
> [`spec.md`](./spec.md) for the design and [`tasks.md`](./tasks.md)
> for the live roadmap.

## What it does

- Central visibility into backup state for every endpoint.
- Trigger any restic operation remotely (`backup`, `forget`,
  `prune`, `check`, `unlock`, `snapshots`, `stats`, `diff`,
  `restore`).
- Per-host schedules with named source groups + retention.
- Live job log streamed to the browser; downloadable as
  text/NDJSON afterwards.
- Restore wizard: browse a snapshot's tree, pick paths, restore
  in-place or to a new directory.
- Repo health surfacing (size, raw size, last check, lock state),
  plus a 30/90-day repo-size trend.
- Alerting over webhook, ntfy, or SMTP.
- Cross-platform agent (Linux systemd + Windows SCM).
- Append-only-friendly: separate admin credential for prune.
- Optional Prometheus `/metrics` endpoint + sample Grafana
  dashboard.
- Optional OIDC SSO (Authelia, Authentik, etc.).

## Screenshots

| Sign in | Empty dashboard | Add host |
|:-------:|:---------------:|:--------:|
| ![Sign in](docs/screenshots/01-login.png) | ![Dashboard, fresh](docs/screenshots/02-dashboard-empty.png) | ![Add host](docs/screenshots/03-add-host.png) |

| Alerts | Settings | Audit log |
|:------:|:--------:|:---------:|
| ![Alerts](docs/screenshots/04-alerts.png) | ![Settings](docs/screenshots/05-settings.png) | ![Audit log](docs/screenshots/06-audit.png) |

(Screenshots from a fresh smoke install with no hosts. A populated
fleet view and the live-log + restore wizard surfaces are part of
the docs site under [`docs/book/`](./docs/book) — `make docs` to
render locally.)

## Architecture (one-line)

A small Go control-plane in Docker, lightweight Go agents on each
endpoint holding an outbound WebSocket to the control-plane, and
a restic repository (rest-server, S3, B2, SFTP — anything restic
speaks) that holds the actual backup data. **The control-plane
never touches backup bytes.**

Full architecture diagram and component breakdown:
[`spec.md` §3](./spec.md), or the rendered version in the
[docs site](./docs/book/src/concepts/architecture.md).

## Repository layout

```
cmd/server/        control-plane binary
cmd/agent/         endpoint agent binary
internal/api       shared API types (REST + WS envelopes)
internal/server/   HTTP, WS, UI handlers, alert engine
internal/agent/    service integration, restic runner, local scheduler
internal/restic    restic CLI wrapper
internal/store     SQLite persistence
internal/crypto    secret encryption (AEAD)
internal/auth      passwords, sessions, agent tokens
web/               server-rendered templates + static assets
deploy/            Dockerfile, docker-compose.yml, install scripts, Grafana dashboard
docs/              prose docs + the mdBook site under docs/book
e2e/               compose stack + Playwright tests for end-to-end CI
```

## Quickstart

The reference deployment is a single Docker container fronted by
your existing reverse proxy. See the [installation guide](docs/book/src/getting-started/install.md)
for the full path; the very short version:

```sh
export RM_VERSION=v0.9.0    # pin a real tag
export RM_BASE_URL=https://restic.example.com
export RM_TRUSTED_PROXY=10.0.0.0/8
docker compose -f deploy/docker-compose.yml up -d
```

The server prints a one-time bootstrap token to the log on first
start. POST it to `/api/bootstrap` (or open `/bootstrap` in a
browser) to create the admin user.

## Local development

Requires Go 1.25+. The floor is set by `modernc.org/sqlite` v1.50.

```sh
make build           # builds cmd/server and cmd/agent into ./bin
make test            # runs go test ./...
make lint            # runs golangci-lint
make smoke-restart   # systemd --user smoke server (see CLAUDE.md)
make docs            # renders the mdBook site to docs/book/book/
```

End-to-end test harness against a Docker Compose stack with a
sibling Linux agent: see [`docs/e2e.md`](docs/e2e.md). Runs in CI
on every PR.

## Documentation

- **Concepts and operator guides**: [docs site](docs/book/src/intro.md),
  rendered with `make docs`.
- **Reverse-proxy setup**: [docs/reverse-proxy.md](docs/reverse-proxy.md).
- **Prometheus + Grafana**: [docs/prometheus.md](docs/prometheus.md).
- **End-to-end test harness**: [docs/e2e.md](docs/e2e.md).
- **Security policy**: [SECURITY.md](SECURITY.md).
- **Contributing**: [CONTRIBUTING.md](CONTRIBUTING.md).

## License

[PolyForm Noncommercial 1.0.0](./LICENSE). Free for personal,
hobby, research, educational, governmental, and other noncommercial
use. Commercial use requires a separate license.
