NAS08 had no automated recovery path. A software or hardware failure â corrupt SD card, bad OMV update, runaway script â would have required a full manual rebuild of OMV, all Docker containers, Pi-hole, Plex, Vaultwarden, Nextcloud, and nginx-proxy-manager with no documented procedure and no saved state.
The goal was to create a fully automated, scheduled backup of the OS and configuration layer â not the NAS data drives â that could restore NAS08 to full operation within approximately 90 minutes after a failure, with no manual intervention during normal operation.
Keep a copy of this document on your workstation, a USB drive, or in print. If NAS08 is down you cannot read files stored on it.
ls /export/kingdezigns-all/Docker ls /export/kingdezigns-all/Docker/Compose
Needed to confirm where application configs and compose files lived before writing backup paths into the script.
Docker root confirmed at /export/kingdezigns-all/Docker/ with Compose subfolder containing all stacks: nextcloud, nginx-proxy-manager, pihole, plex, vaultwarden.
ls -lh /export/kingdezigns-all/Backups/NAS08/nas08-backup-2026-05-11.tar.gz tar -tzf /export/kingdezigns-all/Backups/NAS08/nas08-backup-2026-05-11.tar.gz | head -40
Verified the archive was created and inspected its contents to catch bloat or missing sections.
Archive was 1.4GB â Vaultwarden icon_cache and full Plex config were included without exclusions, inflating the size unnecessarily.
sudo du -sh /export/kingdezigns-all/Docker/Compose/*/ sudo du -sh /export/kingdezigns-all/Docker/pihole/ sudo du -sh /export/kingdezigns-all/Docker/plex/
Identify where archive bulk was coming from before adding exclusions.
Plex at 1.8GB was the dominant size. Pi-hole at 27MB acceptable as-is. Compose folders were tiny (3.5Kâ7.4M each).
sudo du -sh /export/kingdezigns-all/Docker/plex/config/Library/Application\ Support/Plex\ Media\ Server/*/
Identify which Plex subfolders were safe to exclude vs which contained manually curated data worth preserving.
Cache (24M), Logs (2M), Crash Reports (23K) identified as safe exclusions. Media (655M) and Metadata (956M) confirmed as music organization and library data â kept.
sudo zpool list sudo zpool status sudo zfs list
Document exact pool name, drive identifiers, RAID type, and mount point needed for recovery plan ZFS steps.
Pool: kingdezignsnas â RAIDZ2 across 4 Ã 1TB SSDs â ONLINE â mounted at /kingdezignsnas â last scrub clean, no errors.
On first run the backup destination directory did not exist, causing the logging system to fail immediately before any backup work could begin.
Script failed with a tee write error before reaching any backup steps.
tee: /export/kingdezigns-all/Backups/NAS08/backup.log: No such file or directory
Backups/NAS08/ had not been created yet. Fixed by creating it manually. The script now handles this automatically via mkdir -p on every run.
SCP to /usr/local/bin/ failed with permission denied â that path requires root SCP access which rufusking does not have.
Resolution: Created /usr/scripts/omv/ owned by rufusking. SCP now works without root. Script still runs with sudo for root-level operations at runtime.
/usr/scripts/omv/nas08-backup.sh
OMV config â omv-confbak export + raw /etc/openmediavault/config.xml
/etc â full system config (network, fstab, nginx, cron, etc.)
Docker Compose â all stacks + global.env (vaultwarden icon_cache excluded)
Pi-hole data â /export/kingdezigns-all/Docker/pihole/
Plex data â full config minus Cache/, Logs/, Crash Reports/
Media/ and Metadata/ KEPT (music org + library data)
Shared folder â /export/kingdezigns-all/Docker/Shared/
Crontab â root crontab + /etc/cron.d entries
MANIFEST.txt â baked-in restore instructions and OMV version info
/export/kingdezigns-all/Backups/NAS08/nas08-backup-YYYY-MM-DD.tar.gz /export/kingdezigns-all/Backups/NAS08/backup.log
10 archives retained (~30 days coverage) â older archives auto-deleted on each run
~1.4GB per archive â ~14GB total at max retention 450GB free on data drive â well within capacity
System â Scheduled Jobs â Add Name: NAS08 Backup Command: /usr/scripts/omv/nas08-backup.sh Minute: 0 Hour: 2 Day of month: */3 Month: * Day of week: * Runs automatically at 2:00 AM every 3 days
sudo /usr/scripts/omv/nas08-backup.sh # or: OMV UI â System â Scheduled Jobs â Run
You need: a workstation with internet, a replacement SD card (16GB+), Raspberry Pi Imager, SSH access, and your rufusking password. Physically connect all 4 ZFS drives to the Penta SATA HAT before powering on.
https://www.raspberrypi.com/software/
Download and install for your OS (Windows / Mac / Linux).
Open Raspberry Pi Imager
â Choose Device : Raspberry Pi 5
â Choose OS : Raspberry Pi OS Lite (64-bit) â NOT the Desktop version
â Choose Storage : your SD card
â Next â Edit Settings:
Hostname : NAS08
Username : rufusking
Password : your usual password
Services : Enable SSH â Use password authentication
â Save â Yes â Yes (confirm flash and verify)
Wait for the flash and verify to complete fully before removing the SD card.
1. Insert SD card into Raspberry Pi 5 2. Connect Penta SATA HAT with all 4 ZFS drives plugged in 3. Power on 4. Wait 2â3 minutes for first boot to complete
The OMV install method may change in the future. Verify the current script at https://github.com/OpenMediaVault-Plugin-Developers/installScript before running. Steps below reflect the method as of 2026-05-11.
ssh rufusking@192.168.150.35
If the static IP is not yet assigned, log into UniFi at http://192.168.100.1, find NAS08 in Clients, and SSH to its temporary IP instead.
sudo apt-get update && sudo apt-get upgrade -y
Wait for the prompt to return before continuing. This may take a few minutes.
sudo wget -O - https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/install | sudo bash
Takes 10â20 minutes. The Pi may reboot automatically. If it does, SSH back in and wait for the script to finish. Do not interrupt it.
http://192.168.150.35 Default login: Username: admin Password: openmediavault
Confirm the OMV login page loads. Do not configure anything yet â the restore handles all configuration.
The Raspberry Pi 5 does not expose PCIe by default. Without enabling it, the Penta SATA HAT and all 4 ZFS drives are completely invisible to the OS. This must be done before any ZFS commands will work.
sudo nano /boot/firmware/config.txt
Scroll to find the line arm_boost=1 and add these lines immediately after it:
# Enable PCIe dtparam=pciex1 dtparam=pciex1_gen=3
Save and exit:
Ctrl+X â Y â Enter
sudo reboot
Wait 2â3 minutes, then SSH back in:
ssh rufusking@192.168.150.35
sudo apt-get install -y zfsutils-linux
Installs the ZFS kernel modules and CLI tools. Required on every fresh OS install.
lsblk
You should see 4 drives listed (typically sda through sdd). If any are missing, check physical connections and reboot:
sudo reboot # SSH back in, then run lsblk again
sudo zpool import kingdezignsnas
The pool name kingdezignsnas is stored on the drives themselves â it will be recognized on a fresh OS automatically. If the previous OS failed uncleanly, force the import:
# Only use -f if the standard import fails: sudo zpool import -f kingdezignsnas
sudo zpool status
All 4 drives must show ONLINE. Expected output:
pool: kingdezignsnas
state: ONLINE
config:
kingdezignsnas ONLINE
raidz2-0 ONLINE
ata-CT1000BX500SSD1_2539E9CB8529 ONLINE
ata-CT1000BX500SSD1_2534E9C97DAD ONLINE
ata-CT1000BX500SSD1_2530E9C74CD1 ONLINE
ata-CT1000BX500SSD1_2539E9CB84F8 ONLINE
errors: No known data errors
If any drive shows FAULTED or DEGRADED, do not proceed. See ZFS Troubleshooting at the bottom of this document.
sudo zfs list ls /kingdezignsnas/ ls /kingdezignsnas/Backups/NAS08/ # List archives sorted newest first: ls -lht /kingdezignsnas/Backups/NAS08/nas08-backup-*.tar.gz
Use /kingdezignsnas/ directly at this stage. The /export/kingdezigns-all/ path is recreated by OMV after the config restore in Phase 6.
sudo mkdir -p /tmp/nas08-restore
# Replace YYYY-MM-DD with the actual archive date from step 14
sudo tar -xzf /kingdezignsnas/Backups/NAS08/nas08-backup-YYYY-MM-DD.tar.gz \
-C /tmp/nas08-restore
This takes a few minutes â the archive is ~1.4GB. Wait for the prompt to return.
# Confirm all folders are present: ls /tmp/nas08-restore/ ls /tmp/nas08-restore/nas08-backup-*/ # Read the manifest: cat /tmp/nas08-restore/nas08-backup-*/MANIFEST.txt
You should see: omv-config/ etc/ docker-compose/ app-data/ cron/ MANIFEST.txt
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/etc/ /etc/
Restores all system configuration: network settings, nginx, fstab, cron, and everything else under /etc.
# Copy saved OMV config back into place:
sudo cp /tmp/nas08-restore/nas08-backup-*/omv-config/config.xml.raw \
/etc/openmediavault/config.xml
# Load it into the OMV database:
sudo omv-confdbadm populate
# Re-apply all settings to the system (shares, users, plugins, schedules):
sudo omv-salt deploy run all
The last command takes several minutes. Do not interrupt it â let it complete fully.
sudo reboot
After 2â3 minutes, SSH back in and check:
ssh rufusking@192.168.150.35
Then open a browser on your workstation:
http://192.168.150.35
Log in and verify: shares, users, and settings are present. Go to Storage â File Systems and confirm the ZFS pool is mounted and /export/kingdezigns-all is available.
sudo docker ps
If Docker is not found, install it:
sudo apt-get install -y docker-compose-plugin
If the OMV Compose plugin is missing, reinstall via OMV UI:
OMV UI â System â Plugins â search "compose" â Install
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/docker-compose/ \
/export/kingdezigns-all/Docker/Compose/
# Verify files landed correctly:
ls /export/kingdezigns-all/Docker/Compose/
Expected: nextcloud/ nginx-proxy-manager/ pihole/ plex/ vaultwarden/ global.env
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/pihole/ \
/export/kingdezigns-all/Docker/pihole/
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/plex/ \
/export/kingdezigns-all/Docker/plex/
This restores your music organization (Media/), library metadata (Metadata/), and watch history (Plug-in Support/). These are the folders that represent weeks of manual work and are the primary reason this backup exists.
sudo rsync -a /tmp/nas08-restore/nas08-backup-*/app-data/shared/ \
/export/kingdezigns-all/Docker/Shared/
sudo chown -R root:users /export/kingdezigns-all/Docker/ sudo chmod -R 775 /export/kingdezigns-all/Docker/
cd /export/kingdezigns-all/Docker/Compose/pihole && sudo docker compose up -d cd /export/kingdezigns-all/Docker/Compose/nginx-proxy-manager && sudo docker compose up -d cd /export/kingdezigns-all/Docker/Compose/vaultwarden && sudo docker compose up -d cd /export/kingdezigns-all/Docker/Compose/nextcloud && sudo docker compose up -d cd /export/kingdezigns-all/Docker/Compose/plex && sudo docker compose up -d
Start one at a time â not all at once â so errors from individual containers are not lost in combined output.
sudo docker ps
All containers should show status Up. If any show Exited, check that container's logs:
sudo docker logs pihole sudo docker logs nginx-proxy-manager sudo docker logs vaultwarden sudo docker logs nextcloud sudo docker logs plex
ls -lh /usr/scripts/omv/nas08-backup.sh
If missing (it lives outside /etc so may not have restored automatically), copy it from your workstation:
# On your workstation: scp nas08-backup.sh rufusking@192.168.150.35:/usr/scripts/omv/nas08-backup.sh # On NAS08: chmod +x /usr/scripts/omv/nas08-backup.sh
sudo crontab /tmp/nas08-restore/nas08-backup-*/cron/root-crontab.txt # Verify it was applied: sudo crontab -l
OMV UI â System â Scheduled Jobs â Add Enabled: Yes Name: NAS08 Backup Command: /usr/scripts/omv/nas08-backup.sh Minute: 0 Hour: 2 Day of month: */3 Month: * Day of week: * â Save
sudo rm -rf /tmp/nas08-restore
# Option A â OMV UI: System â Scheduled Jobs â NAS08 Backup â Run # Option B â SSH on NAS08: sudo /usr/scripts/omv/nas08-backup.sh # Verify it completed successfully: ls -lh /export/kingdezigns-all/Backups/NAS08/ cat /export/kingdezigns-all/Backups/NAS08/backup.log
sudo zpool scrub kingdezignsnas # Check results a few minutes later: sudo zpool status
A healthy result:
scan: scrub repaired 0B in 00:xx:xx with 0 errors
sudo zpool status â failed drive shows FAULTED or UNAVAIL
RAIDZ2 tolerates up to 2 simultaneous drive failures. The pool is still fully readable and writable. Complete the full restore procedure first, then replace the failed drive. Do not skip recovery steps.
sudo zpool status â two drives show FAULTED or UNAVAIL
Data is at risk but still accessible. Complete the restore immediately and replace both drives as fast as possible. Seek assistance before doing anything else if unsure.
# Scan all connected devices for importable pools: sudo zpool import # If kingdezignsnas appears in the list, force import: sudo zpool import -f kingdezignsnas
If no pools are found at all, PCIe is likely not enabled. Verify Steps 8â9 (boot config) were applied correctly and reboot again before retrying.
# Access backup files directly via the ZFS mount point: ls /kingdezignsnas/Backups/NAS08/
/export/kingdezigns-all/ is created by OMV when it mounts the filesystem. Use /kingdezignsnas/ as the base path for all restore commands until OMV is fully restored.
| Lesson | Detail |
|---|---|
| PCIe must be enabled before ZFS can see the drives | The Raspberry Pi 5 Penta SATA HAT requires PCIe to be explicitly enabled in /boot/firmware/config.txt. On a fresh OS this is never set. Without it all 4 ZFS drives are invisible and the pool cannot be imported. |
| ZFS pool import must happen before any restore steps | Without importing the pool, the backup files are completely inaccessible. It is now Phase 4, immediately after enabling PCIe, before any restore work begins. |
| Plex Media/ and Metadata/ contain irreplaceable manually curated data | These folders hold music organization, artwork, and library structure that took weeks of manual work. They must always be included in backups even though they are large (~1.6GB combined). |
| Never run scripts that touch OMV without a tested recovery plan first | A prior script run by another AI tool broke OMV and wiped Plex music organization. This session was motivated by that incident. Backup first, change second. |
| Custom scripts belong in /usr/scripts/ not /usr/local/bin/ | Writing to /usr/local/bin/ requires root SCP access. A dedicated /usr/scripts/ directory owned by rufusking avoids this and keeps custom scripts separated from system binaries. |
| Always create output directories before the first script run | The script failed on first run because /Backups/NAS08/ did not exist. The script now handles this automatically via mkdir -p, but always verify the path exists before the first run on a new system. |
| Vaultwarden icon_cache is large and completely disposable | The icon cache for website favicons was inflating the archive. It regenerates automatically and must always be excluded. |
| Recovery documentation must be stored off the device being recovered | A recovery plan stored only on NAS08 is useless when NAS08 is down. Keep copies on a workstation, USB drive, or in print. |
| Item | Old value | New value |
|---|---|---|
| NAS08 â Hardware detail | Raspberry Pi |
Raspberry Pi 5 with Penta SATA HAT |
| NAS08 â Backup status | None |
Automated â every 3 days â 30-day retention |
| NAS08 â Backup destination | None |
/export/kingdezigns-all/Backups/NAS08/ |
| NAS08 â Backup script | None |
/usr/scripts/omv/nas08-backup.sh |
| NAS08 â ZFS pool name | not documented |
kingdezignsnas (RAIDZ2, 4 Ã 1TB SSD) |
| NAS08 â ZFS mount point | not documented |
/kingdezignsnas |
| NAS08 â PCIe requirement | not documented |
dtparam=pciex1 + dtparam=pciex1_gen=3 required in /boot/firmware/config.txt on fresh OS |
| NAS08 â Recovery plan | None |
NAS08-Backup-Summary.html â 34 steps across 9 phases + ZFS troubleshooting |