Restores¶
Every asset class, with the exact commands. Rule of the house: a backup isn't real until you've restored from it — after any change here, restore one file and open it.
The Kopia restore footgun (verified 2026-08-09)
If a kopia restore target path ends in .tar.gz or .zip, kopia
switches into archive-wrapping mode and writes a new archive containing
the restored content — different bytes than the original file. To get a
file back byte-identical (e.g. a Minecraft world tarball), restore to an
extension-less path and rename afterwards. Verified: sha256 matches
with a plain target, differs with a .tar.gz target.
Which restore path?¶
flowchart TD
start(["What did you lose?"])
start --> file["A file or folder"]
file --> kopia["Kopia: browse the snapshot in the UI,<br/>or CLI restore to an extension-less path"]
start --> vm["A whole VM"]
vm --> qm["qmrestore from the NAS dump<br/>(restore BESIDE the original)"]
start --> world["A Minecraft world"]
world --> t1["mc-admin → Backups → Restore<br/>(covers ~14 days + weeklies)"]
t1 -- "need older?" --> t2["kopia backup@mc<br/>(30 daily + 52 weekly)"]
start --> machine["A whole machine"]
machine --> mw["Windows: Veeam recovery USB (Phase 2)<br/>MacBook: Time Machine at home + Kopia files"]
start --> nas["The NAS itself"]
nas --> dr["VM dumps: Google Drive (latest set)<br/>Kopia repo: needs the vaulted password<br/>(no cloud copy yet — B2 pending)"]
Single file (Kopia — any endpoint)¶
GUI (MacBook and other KopiaUI machines):
- KopiaUI → Snapshots → click the folder → pick a point in time.
- Browse to the file → Restore (to a new location) or Download.
CLI (any machine connected to the repo):
kopia snapshot list <path> # find the snapshot id
kopia restore <snapshot-id>/<sub/path> /tmp/restored
Remember the footgun above: /tmp/restored, not /tmp/restored.tar.gz.
Whole VM or container (vzdump)¶
On the PVE host:
# what exists
ls -lh /mnt/pve/pbs/dump/
# restore BESIDE the original (pick a free VMID), or reuse the VMID to replace it
qmrestore /mnt/pve/pbs/dump/vzdump-qemu-<vmid>-<stamp>.vma.zst <target-vmid> \
--storage local-lvm --unique 1
Single file from inside a VM dump (verified 2026-08-08)¶
Restore the dump to a scratch VMID (as above, don't start it), then loop-mount its disk read-only:
LOOP=$(losetup -fP --show /dev/pve/vm-<scratch-id>-disk-1)
mount -o ro ${LOOP}p1 /mnt/restore-check
cp /mnt/restore-check/<path/to/file> <destination>
umount /mnt/restore-check && losetup -d $LOOP
qm destroy <scratch-id> --purge 1
Whole Windows machine (Veeam)¶
Phase 2 — not configured yet
The Windows PCs and tablet don't have Veeam jobs yet. This is the procedure once they do.
Boot the machine's labelled recovery USB → Bare Metal Recovery → point
it at \\<NAS>\veeam\<machine>\. For individual files instead of a full
image: Veeam GUI → File Level Restore.
Minecraft world (two tiers)¶
Tier 1 — last ~2 months: the mc-admin UI
(https://mc-admin.byers.cc → Restore) reads the VM-local
14-daily + 8-weekly tarballs in ~/bedrock_backups directly. This is the
normal path.
Tier 2 — deeper history (30 daily + 52 weekly): the same tarballs are
snapshotted nightly to the NAS Kopia repo as backup@mc. On the Minecraft
VM, as the minecraft user:
~/bin/kopia snapshot list /home/minecraft/bedrock_backups # pick the epoch
~/bin/kopia restore <id>/<world>/backup_<stamp>.tar.gz /tmp/w # NO extension on the target!
Then move /tmp/w into ~/bedrock_backups/<world>/backup_<stamp>.tar.gz
(needs root — the directories are root-owned), and restore through mc-admin
as usual. The full server-side context is in the
Minecraft runbook.
Disaster: NAS dead¶
Prerequisite before anything else: the Kopia repo password (vaulted —
password manager, master copy in /etc/backup-stack/kopia.env on ops).
Without it the repo is unreadable, from any copy, anywhere.
VM dumps — the latest set is in Google Drive:
rclone copy gdrive:VM-Dumps /some/disk --config /root/.config/rclone/rclone.conf
# then qmrestore from /some/disk as in the vzdump section above
Run on ops, or any box with the rclone config.
Kopia data (MacBook + Minecraft history) — currently NAS-only, no cloud copy (deliberate; see off-site). If the NAS dies today, Kopia history dies with it — the live source machines still hold their current files. Once a cloud copy exists (B2 is the standing plan), recovery is:
kopia repository connect b2 ... # from B2, or:
kopia repository connect rclone --remote-path gdrive:Kopia-Repo
then single-file restores as above, using the vaulted repo password.
NAS snapshots are the ransomware layer
The NAS-side snapshots of the backup shares (enabled in the NAS UI) are what protect against an attacker or bug deleting the backups themselves — see attack response.