Files
vh de1eac2904 restic/nh3-docker: profile + deployment guide
Adds file-level restic for the NH3 Docker VM. Targets the Synology
rest-server (rest-server-nh3 at 10.100.50.50:8000) as user nh3-docker —
site-local writes matching the fleet pattern.

No pre-backup hook needed: none of the stacks on this host (adguard,
dockge, beszel-agent, dozzle-agent, portainer) run relational DBs. The
SQLite state in their named volumes is WAL-mode and restores cleanly
from raw restic capture.

Source paths mirror ana-ml2's template (/opt/docker, /etc, /root,
/var/lib/docker/volumes) with the same exclude list (docker internals,
logs, pids, root's shell/caches). ~1.6 MB of compose files + small
volumes — expected snapshot size a few hundred MB at most, dominated
by any AdGuard query log history.

README walks through reuse (existing repo + htpasswd) vs fresh init
paths, resticprofile install, timer generation, and verification via
the Backrest UI.
2026-04-21 01:13:35 -07:00

163 lines
4.9 KiB
Markdown

# restic / nh3-docker
VM on `nh3-pve` at the NH3 site. Backed up two ways:
- **VM image** via Proxmox vzdump (covered 5/5 on nh3-pve). Good for full-VM restore after catastrophic failure.
- **File-level restic** (this config). Fast per-file restore and site-resilient off-site copy. Writes to the Synology rest-server (`10.100.50.50:8000`) as user `nh3-docker`.
## What's backed up
| Path | Purpose |
|---|---|
| `/opt/docker` | Compose files (~1.6 MB) |
| `/etc` | Host config — systemd, ssh, chrony, apparmor, apt, etc. |
| `/root` | Root's ad-hoc scripts, shell history, ssh keys |
| `/var/lib/docker/volumes` | AdGuard confdir + workdir, beszel-agent, dozzle-agent, dockge state, portainer state |
## Not backed up
- `*.log`, `*.pid`, `.../logs/` directories
- `/root/.cache`, `/root/.npm`, shell-noise caches
## No pre-backup hook needed
Unlike ana-docker, nh3-docker runs no relational databases. The volumes
captured above contain SQLite files for dockge / beszel-agent /
dozzle-agent / portainer — all low-transaction, WAL-mode, and restic's
raw-file capture restores cleanly.
AdGuard config lives in `/var/lib/docker/volumes/adguard_adguard-confdir/`
as plain YAML. No consistency concerns.
## Deploy (one-time setup)
### 1. Check for existing repo + htpasswd
The Synology rest-server at `10.100.50.50` may already have an `nh3-docker`
entry in its `.htpasswd` and a repo at `/nh3-docker/` from an earlier
setup pass. See `stacks/rest-server-nh3/README.md` for the Synology-side
layout.
If a repo + htpasswd exist and you have the passphrase: follow the
**reuse** path (skip init, install the existing secrets).
If not: follow the **fresh** path below.
### 2. Install restic creds on nh3-docker
```bash
ssh -t nh3-docker '
sudo install -d -o root -g root -m 0700 /etc/restic /var/lib/restic
'
# REST URL (with HTTP basic-auth creds embedded) — paste from password manager
ssh -t nh3-docker 'sudo bash -c "cat > /etc/restic/restic.env && chmod 600 /etc/restic/restic.env"'
# paste: RESTIC_REPOSITORY=rest:http://nh3-docker:<HTPASSWD-PW>@10.100.50.50:8000/nh3-docker/
# Ctrl-D
# Encryption passphrase — paste from password manager
ssh -t nh3-docker 'sudo bash -c "cat > /etc/restic/password && chmod 600 /etc/restic/password"'
# paste: <REPO-PASSPHRASE>
# Ctrl-D
```
### 3. Verify creds against the repo
```bash
ssh -t nh3-docker '
sudo bash -c "
set -a; . /etc/restic/restic.env; set +a
RESTIC_PASSWORD_FILE=/etc/restic/password restic snapshots
"
'
```
Expected: either a list of existing snapshots, or `no snapshots found`
on a fresh repo. Both are fine.
If you get `wrong password or no key found`, the passphrase doesn't
match. Check your password manager or follow the "Recreating the repo"
path below.
### 4. Fresh-init (only if no repo exists yet on the Synology)
```bash
ssh -t nh3-docker '
sudo bash -c "
set -a; . /etc/restic/restic.env; set +a
restic init
"
'
# enter passphrase twice at the prompt
```
### 5. Install resticprofile
```bash
ssh -t nh3-docker '
curl -sfL https://raw.githubusercontent.com/creativeprojects/resticprofile/master/install.sh \
| sudo sh -s -- -b /usr/local/bin
/usr/local/bin/resticprofile version
'
```
### 6. Deploy the profile
```bash
scp configs/restic/nh3-docker/profiles.yaml nh3-docker:/tmp/profiles.yaml
ssh -t nh3-docker '
sudo install -o root -g root -m 0644 /tmp/profiles.yaml /etc/restic/profiles.yaml &&
rm /tmp/profiles.yaml &&
sudo resticprofile --config /etc/restic/profiles.yaml show
'
```
### 7. Enable systemd timers
```bash
ssh -t nh3-docker '
sudo resticprofile --config /etc/restic/profiles.yaml schedule --all &&
systemctl list-timers "resticprofile*"
'
```
### 8. First backup
```bash
ssh -t nh3-docker 'sudo resticprofile --config /etc/restic/profiles.yaml backup --verbose'
```
Expected size: **a few hundred MB** (adguard's data dir can hold cache +
query log, which is the bulk). If you see >2 GB on first run, check for
old AdGuard query logs under `/var/lib/docker/volumes/adguard_adguard-workdir/`
and decide whether to exclude them.
Verify in Backrest UI (`http://10.250.50.70:9898`) — `nh3-docker` repo
should show the new snapshot within a minute.
## Restoring
```bash
ssh -t nh3-docker '
sudo bash -c "
set -a; . /etc/restic/restic.env; set +a
RESTIC_PASSWORD_FILE=/etc/restic/password \
restic restore --target /tmp/restore latest --path /opt/docker
"
'
```
## Recreating the repo (lost passphrase)
Same pattern as ana-ml2 but targets the Synology rest-server. See
`configs/restic/ana-ml2/README.md` for the wipe-and-reinit recipe;
substitute:
- rest-server host `10.100.50.50` instead of `10.250.50.70`
- repo path `/nh3-docker/` under the Synology's rest-server data root
(location depends on that stack's `DATA_DIR` — see
`stacks/rest-server-nh3/README.md`)
- SSH into the Synology directly requires enabling SSH in DSM + key
setup (tabled in an earlier session)