Skip to content

VM 100 restore — VALIDATED

Extracted from the master document on 2026-09-04. The §N numbering is kept so cross-references are not broken.

46. Full restore of VM 100 — ✅ VALIDATED (2026-09-03 / 09-04)

Section titled “46. Full restore of VM 100 — ✅ VALIDATED (2026-09-03 / 09-04)”

Two steps over two days. On 2026-09-03 VM 100 was restored as VM 199 and the real boot was validated: filesystem, Debian, Docker, volumes and Vaultwarden responding. On 2026-09-04 the missing part was closed out — that the archive came from R2, not from the local copy (§48).

Backup: /var/lib/vz/dump/vzdump-qemu-100-2026_08_30-02_07_51.vma.zst
Size: ~15,7 GB decimal / ~14,7 GiB
Terminal window
sudo pvesm extractconfig local:backup/vzdump-qemu-100-2026_08_30-02_07_51.vma.zst
cores: 2 · memory: 4096 · name: docker-host
scsi0: local-lvm, size=50G
scsi1: /dev/disk/by-id/ata-WDC_WD10EZEX-... backup=0 ◄── key
net0: virtio=BC:24:11:94:CE:48, bridge=vmbr0, firewall=1
vzdump VM 100
├── scsi0 SSD virtual disk (50G) → INCLUDED
└── scsi1 1 TB physical HDD → NOT INCLUDED (backup=0)
│
the Nextcloud data is NOT in this archive.
It comes via Layer 2 + AIO's native backup.

The restore was not done from the local copy of the dump, but from the archive downloaded from R2 (see §48) — that is the difference that turns this into a real disaster recovery test and not a disk-to-disk copy within the same node.

Terminal window
sudo qmrestore <archive-descargado-de-R2>.vma.zst 199 --storage local-lvm

⚠️ VM 199 MUST NOT be booted without isolating it first. It is an exact clone of production: same IP, same MAC, same Tailscale identity, and a reference to the same physical HDD.

1. inspect `qm config 199` ✅
2. prevent simultaneous access to the physical HDD ✅
3. isolate / disconnect the NIC ✅
4. avoid IP conflict on 192.168.2.8 ✅
5. avoid duplicate Tailscale identity ✅
6. boot it isolated ✅
7. validate filesystem, Debian, Docker and configuration ✅
8. destroy VM 199 when finished ⏳ PENDING
VM 100 production → intact
VM 199 restore-test → booted and validated correctly
VM restore end-to-end → ✅ APPROVED

What this test proves: that starting from an off-site copy and nothing else, docker-host can be brought back up. What is still not proven: that the ~129 GB of Nextcloud come back — that is not in this archive (§46.1) and its restore is still deferred (§47).

46.3 Immediate open item — destroy VM 199

Section titled “46.3 Immediate open item — destroy VM 199”

This is not a formality. As long as it exists, an accidental boot of VM 199 puts a second machine on the LAN with IP 192.168.2.8, MAC BC:24:11:94:CE:48 and docker-host’s Tailscale identity — and with a reference to the same physical HDD that production has mounted for writing.

Terminal window
sudo /usr/sbin/qm status 199 # confirm that it is stopped
sudo /usr/sbin/qm destroy 199 # and free up the ~50 GB of local-lvm

46.4 Lessons from the VM 199 restore — read BEFORE the next one

Section titled “46.4 Lessons from the VM 199 restore — read BEFORE the next one”

Four things that cost time the first time round and need not cost any the second:

1. The clone boots into emergency mode. It is not that the restore failed: /etc/fstab mounts the physical HDD (scsi1) by UUID, and that disk was deliberately not attached to the clone, so systemd hangs waiting for it.

BEFORE booting the VM for the first time, edit its /etc/fstab:
comment out the line with the HDD's UUID
— or —
add to it: nofail,x-systemd.device-timeout=5s

2. Tailscale starts on its own, with the identity of the real VM 100. Two nodes claiming the same identity in the tailnet. Stop it as soon as it boots:

Terminal window
sudo systemctl stop tailscaled
sudo systemctl disable tailscaled

3. Containers with restart: unless-stopped also start on their own — including Caddy, publishing 80/443 on 0.0.0.0. That can interfere with production’s DNS-01 renewal. Stop everything except whatever is being validated at that moment.

4. The Proxmox noVNC console (1.7.0-2) loses keyboard focus when switching tabs — you have to click inside the black area again — and it has no paste panel; xterm.js appeared but could not be selected. Practical conclusion: type short commands, one at a time, instead of long blocks.