KingDezigns โ€” NAS16 Automated Backup Setup Summary

๐Ÿ“… 2026-05-12 ๐Ÿ–ฅ NAS16 / Raspberry Pi 5 โš™๏ธ OpenMediaVault (OMV) ๐ŸŒ Apache ยท PHP ยท MariaDB ยท Webmin ๐Ÿ’พ ZFS RAIDZ2 โ€” Penta SATA HAT
The goal

NAS16 serves live websites via Apache/PHP and hosts their databases in MariaDB. A software or hardware failure โ€” corrupt SD card, bad OMV update, runaway script โ€” would take down all hosted sites and lose database state with no documented recovery path and no saved configuration.

No OS backup No database backup No automated recovery plan Web server config undocumented

The goal was to create a fully automated, scheduled backup of the OS and configuration layer โ€” including all databases โ€” that could restore NAS16 to full operation after a failure with no manual intervention during normal operation. Website files on the NAS drives are intentionally excluded; those are covered separately by NAS-to-NAS redundancy.

โš  Critical โ€” store this document off NAS16

Keep a copy of this document on your workstation, a USB drive, or in print. If NAS16 is down you cannot read files stored on it.

What is backed up
Backup Script Location
/usr/scripts/omv/nas16-backup.sh
What It Backs Up
OMV config        โ€” omv-confbak export + raw /etc/openmediavault/config.xml
/etc              โ€” full system config (network, fstab, cron, etc.)
Apache config     โ€” sites-available, sites-enabled, mods-enabled, conf-available,
                    conf-enabled, apache2.conf
PHP config        โ€” all installed PHP version ini + FPM pool configs (/etc/php/*)
MariaDB databases โ€” mysqldump of every user database (.sql.gz per database)
                    system schemas excluded (information_schema, performance_schema,
                    sys, mysql)
Webmin config     โ€” /etc/webmin (Webmin and Adminer settings)
Crontab           โ€” root crontab + /etc/cron.d entries
MANIFEST.txt      โ€” baked-in restore instructions and version info

NOT INCLUDED (by design):
  Website files on NAS drives โ€” covered by NAS-to-NAS redundancy
Output Paths
/export/kingdezignsnas-16/Backups/NAS16/nas16-backup-YYYY-MM-DD.tar.gz
/export/kingdezignsnas-16/Backups/NAS16/backup.log
Retention
10 archives retained (~30 days coverage) โ€” older archives auto-deleted on each run
Expected Size
Varies based on database sizes โ€” /etc + Apache + PHP + Webmin are small.
Primary size driver is MariaDB dumps. Monitor backup.log after first run for actual size.
Schedule via OMV UI
System โ†’ Scheduled Jobs โ†’ Add
  Name:          NAS16 Backup
  Command:       sudo /usr/scripts/omv/nas16-backup.sh
  Minute:        0
  Hour:          2
  Day of month:  */3
  Month:         *
  Day of week:   *
Runs automatically at 2:00 AM every 3 days
Manual Run
sudo /usr/scripts/omv/nas16-backup.sh
# or: OMV UI โ†’ System โ†’ Scheduled Jobs โ†’ Run
Initial setup steps
1 Create the scripts directory โ€” NAS16
sudo mkdir -p /usr/scripts/omv
sudo chown rufusking:rufusking /usr/scripts/omv

Placing scripts in /usr/scripts/omv/ avoids the root-SCP requirement of /usr/local/bin/. The rufusking user can copy files here directly.

2 Create the backup destination โ€” NAS16
sudo mkdir -p /export/kingdezignsnas-16/Backups/NAS16

The script creates this automatically via mkdir -p on every run, but creating it manually avoids a tee log error on the very first run if the path doesn't exist yet.

3 Copy the script to NAS16 โ€” workstation
# From your workstation:
scp nas16-backup.sh rufusking@<NAS16-IP>:/usr/scripts/omv/nas16-backup.sh
4 Make the script executable โ€” NAS16
chmod +x /usr/scripts/omv/nas16-backup.sh
5 Run a test backup โ€” NAS16
sudo /usr/scripts/omv/nas16-backup.sh

Watch for any WARNING or ERROR lines in the output. Then verify the archive was created:

ls -lh /export/kingdezignsnas-16/Backups/NAS16/
cat /export/kingdezignsnas-16/Backups/NAS16/backup.log
6 Inspect archive contents โ€” NAS16
tar -tzf /export/kingdezignsnas-16/Backups/NAS16/nas16-backup-$(date +%Y-%m-%d).tar.gz | head -60

You should see folders: omv-config/ etc/ apache/ php/ databases/ webmin/ cron/ MANIFEST.txt

7 Schedule the job in OMV UI โ€” NAS16
OMV UI โ†’ System โ†’ Scheduled Jobs โ†’ Add
  Enabled:       Yes
  Name:          NAS16 Backup
  Command:       sudo /usr/scripts/omv/nas16-backup.sh
  Minute:        0
  Hour:          2
  Day of month:  */3
  Month:         *
  Day of week:   *
โ†’ Save โ†’ Apply
Full recovery procedure
โš  Before You Start

You need: a workstation with internet, a replacement SD card (16GB+), Raspberry Pi Imager, SSH access, and your rufusking password. Physically connect all ZFS drives to the Penta SATA HAT before powering on.

Phase 1 โ€” Flash the OS
1 Download Raspberry Pi Imager โ€” workstation
https://www.raspberrypi.com/software/

Download and install for your OS (Windows / Mac / Linux).

2 Flash Raspberry Pi OS Lite (64-bit) โ€” workstation
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  : NAS16
    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.

3 Boot the Raspberry Pi
1. Insert SD card into Raspberry Pi 5
2. Connect Penta SATA HAT with all ZFS drives plugged in
3. Power on
4. Wait 2โ€“3 minutes for first boot to complete
Phase 2 โ€” Install OpenMediaVault
โš  Note

Verify the current OMV install script at https://github.com/OpenMediaVault-Plugin-Developers/installScript before running. Steps below reflect the method as of 2026-05-12.

4 SSH into NAS16 โ€” workstation
ssh rufusking@<NAS16-IP>

If the static IP is not yet assigned, log into UniFi, find NAS16 in Clients, and SSH to its temporary IP instead.

5 Update the OS โ€” NAS16
sudo apt-get update && sudo apt-get upgrade -y

Wait for the prompt to return before continuing.

6 Install OpenMediaVault โ€” NAS16
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.

7 Verify OMV is running โ€” browser on workstation
http://<NAS16-IP>

Default login:
  Username: admin
  Password: openmediavault

Confirm the OMV login page loads. Do not configure anything yet โ€” the restore handles all configuration.

Phase 3 โ€” Enable PCIe for Penta SATA HAT

The Raspberry Pi 5 does not expose PCIe by default. Without enabling it, the Penta SATA HAT and all ZFS drives are completely invisible to the OS. This must be done before any ZFS commands will work.

8 Edit boot config to enable PCIe โ€” NAS16
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
9 Reboot to apply PCIe config โ€” NAS16
sudo reboot

Wait 2โ€“3 minutes, then SSH back in.

Phase 4 โ€” Import ZFS Pool
10 Install ZFS tools โ€” NAS16
sudo apt-get install -y zfsutils-linux

Required on every fresh OS install.

11 Verify all drives are visible โ€” NAS16
lsblk

All drives attached to the Penta SATA HAT should be listed. If any are missing, check physical connections and reboot.

12 Import the ZFS pool โ€” NAS16
sudo zpool import kingdezignsnas-16

If the previous OS failed uncleanly, force the import:

# Only use -f if the standard import fails:
sudo zpool import -f kingdezignsnas-16
13 Verify pool imported correctly โ€” NAS16
sudo zpool status

All drives must show ONLINE and errors should be No known data errors.

If any drive shows FAULTED or DEGRADED, do not proceed. See ZFS Troubleshooting at the bottom of this document.

14 Confirm backup files are accessible โ€” NAS16
ls /kingdezignsnas-16/Backups/NAS16/

# List archives sorted newest first:
ls -lht /kingdezignsnas-16/Backups/NAS16/nas16-backup-*.tar.gz

Use /kingdezignsnas-16/ directly at this stage. The /export/kingdezignsnas-16/ path is recreated by OMV after the config restore in Phase 6.

Phase 5 โ€” Extract the Backup Archive
15 Create restore working directory โ€” NAS16
sudo mkdir -p /tmp/nas16-restore
16 Extract the most recent backup โ€” NAS16
# Replace YYYY-MM-DD with the actual archive date from step 14
sudo tar -xzf /kingdezignsnas-16/Backups/NAS16/nas16-backup-YYYY-MM-DD.tar.gz \
    -C /tmp/nas16-restore
17 Confirm extraction and read the manifest โ€” NAS16
ls /tmp/nas16-restore/
ls /tmp/nas16-restore/nas16-backup-*/

cat /tmp/nas16-restore/nas16-backup-*/MANIFEST.txt

You should see: omv-config/  etc/  apache/  php/  databases/  webmin/  cron/  MANIFEST.txt

Phase 6 โ€” Restore System Configuration
18 Restore /etc โ€” NAS16
sudo rsync -a /tmp/nas16-restore/nas16-backup-*/etc/ /etc/

Restores all system configuration: network settings, fstab, cron, and everything else under /etc.

19 Restore OMV configuration โ€” NAS16
# Copy saved OMV config back into place:
sudo cp /tmp/nas16-restore/nas16-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:
sudo omv-salt deploy run all

The last command takes several minutes. Do not interrupt it โ€” let it complete fully.

20 Reboot and verify OMV โ€” NAS16 then browser
sudo reboot

After 2โ€“3 minutes, SSH back in. Then open a browser:

http://<NAS16-IP>

Log in and verify shares, users, and settings are present. Confirm the ZFS pool is mounted and /export/kingdezignsnas-16 is available under Storage โ†’ File Systems.

Phase 7 โ€” Reinstall Web Stack (Apache, PHP, MariaDB, Webmin)
โš  Install First, Restore Config Second

The web stack packages must be reinstalled before restoring configuration files. Restoring config before the packages exist will have no effect and may be overwritten by the installer.

21 Install Apache and PHP โ€” NAS16
sudo apt-get install -y apache2 php libapache2-mod-php php-mysql php-cli php-curl \
    php-mbstring php-xml php-zip php-gd

Install the same PHP version that was running before. Check the MANIFEST.txt from the archive for the exact version if unsure.

22 Install MariaDB โ€” NAS16
sudo apt-get install -y mariadb-server mariadb-client
23 Secure MariaDB and verify it is running โ€” NAS16
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo systemctl status mariadb

Do NOT run mysql_secure_installation before restoring databases โ€” the debian.cnf maintenance account needs to remain intact for the restore steps to work without a password.

24 Install Webmin โ€” NAS16
# Add Webmin repository and install:
curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh
sudo sh setup-repos.sh
sudo apt-get install -y webmin

Verify the current install method at https://webmin.com/download/ before running โ€” the method may change.

25 Install Adminer โ€” NAS16
sudo apt-get install -y adminer
sudo a2enconf adminer
sudo systemctl reload apache2

Or manually place adminer.php in your web root if you use a custom location:

sudo wget -O /var/www/html/adminer.php https://www.adminer.org/latest.php
Phase 8 โ€” Restore Web Stack Configuration
26 Restore Apache configuration โ€” NAS16
sudo rsync -a /tmp/nas16-restore/nas16-backup-*/apache/sites-available/ \
    /etc/apache2/sites-available/

sudo rsync -a /tmp/nas16-restore/nas16-backup-*/apache/sites-enabled/ \
    /etc/apache2/sites-enabled/

sudo rsync -a /tmp/nas16-restore/nas16-backup-*/apache/conf-available/ \
    /etc/apache2/conf-available/

sudo rsync -a /tmp/nas16-restore/nas16-backup-*/apache/conf-enabled/ \
    /etc/apache2/conf-enabled/

# Restore main apache2.conf:
sudo cp /tmp/nas16-restore/nas16-backup-*/apache/apache2.conf \
    /etc/apache2/apache2.conf

Do not overwrite mods-enabled directly โ€” Apache manages these symlinks internally. Re-enable required mods manually if needed (see step 27).

27 Re-enable Apache modules โ€” NAS16
# Check what modules were enabled (from your backup):
ls /tmp/nas16-restore/nas16-backup-*/apache/mods-enabled/

# Re-enable common modules as needed:
sudo a2enmod rewrite ssl headers proxy proxy_http
sudo systemctl restart apache2

Enable only the mods you see in the backup snapshot. The full list is in the mods-enabled/ folder inside the archive.

28 Restore PHP configuration โ€” NAS16
# Replace X.X with your PHP version (e.g. 8.2):
sudo rsync -a /tmp/nas16-restore/nas16-backup-*/php/X.X/ /etc/php/X.X/
29 Restore Webmin configuration โ€” NAS16
sudo rsync -a /tmp/nas16-restore/nas16-backup-*/webmin/ /etc/webmin/
30 Restart web stack services โ€” NAS16
sudo systemctl restart apache2
sudo systemctl restart mariadb
sudo systemctl restart webmin

# Verify all are running:
sudo systemctl status apache2 mariadb webmin
Phase 9 โ€” Restore Databases
31 List backed-up databases โ€” NAS16
ls /tmp/nas16-restore/nas16-backup-*/databases/

You should see one .sql.gz file per database. Each file is a complete dump of that database including schema and data.

32 Restore each database โ€” NAS16
# For each database (replace DB_NAME with the actual name):
gunzip -c /tmp/nas16-restore/nas16-backup-*/databases/DB_NAME.sql.gz \
    | sudo mysql --defaults-file=/etc/mysql/debian.cnf DB_NAME

# If the database does not exist yet, create it first:
sudo mysql --defaults-file=/etc/mysql/debian.cnf \
    -e "CREATE DATABASE IF NOT EXISTS DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# Then restore:
gunzip -c /tmp/nas16-restore/nas16-backup-*/databases/DB_NAME.sql.gz \
    | sudo mysql --defaults-file=/etc/mysql/debian.cnf DB_NAME

Repeat for every .sql.gz file in the databases/ folder. Take your time โ€” one at a time to catch any individual errors.

33 Verify databases restored correctly โ€” NAS16
sudo mysql --defaults-file=/etc/mysql/debian.cnf \
    -e "SHOW DATABASES;"

# Spot-check row counts in a key table (replace DB_NAME and TABLE_NAME):
sudo mysql --defaults-file=/etc/mysql/debian.cnf \
    -e "SELECT COUNT(*) FROM DB_NAME.TABLE_NAME;"
Phase 10 โ€” Final Steps & Verification
34 Restore the crontab โ€” NAS16
sudo crontab /tmp/nas16-restore/nas16-backup-*/cron/root-crontab.txt

# Verify it was applied:
sudo crontab -l
35 Reschedule the backup job in OMV UI โ€” NAS16
OMV UI โ†’ System โ†’ Scheduled Jobs โ†’ Add
  Enabled:       Yes
  Name:          NAS16 Backup
  Command:       sudo /usr/scripts/omv/nas16-backup.sh
  Minute:        0
  Hour:          2
  Day of month:  */3
  Month:         *
  Day of week:   *
โ†’ Save โ†’ Apply
36 Copy the backup script back to NAS16 โ€” workstation
scp nas16-backup.sh rufusking@<NAS16-IP>:/usr/scripts/omv/nas16-backup.sh
chmod +x /usr/scripts/omv/nas16-backup.sh

The script lives outside /etc so it is not automatically restored by the /etc rsync. Always re-deploy it manually.

37 Verify all websites load โ€” browser
# Test each hosted domain or IP in your browser.
# Check Apache error log if anything fails:
sudo tail -50 /var/log/apache2/error.log
38 Clean up the restore working directory โ€” NAS16
sudo rm -rf /tmp/nas16-restore
39 Run a fresh backup immediately to create a new baseline โ€” NAS16
# Option A โ€” OMV UI:
System โ†’ Scheduled Jobs โ†’ NAS16 Backup โ†’ Run

# Option B โ€” SSH on NAS16:
sudo /usr/scripts/omv/nas16-backup.sh

# Verify it completed successfully:
ls -lh /export/kingdezignsnas-16/Backups/NAS16/
cat /export/kingdezignsnas-16/Backups/NAS16/backup.log
40 Run a ZFS scrub to verify data integrity โ€” NAS16
sudo zpool scrub kingdezignsnas-16

# Check results a few minutes later:
sudo zpool status

A healthy result:

scan: scrub repaired 0B in 00:xx:xx with 0 errors
ZFS Troubleshooting
โ€” Pool shows DEGRADED โ€” 1 drive failed
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.

โ€” Pool shows DEGRADED โ€” 2 drives failed
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.

โ€” Pool cannot be imported โ€” not found
# Scan all connected devices for importable pools:
sudo zpool import

# If kingdezignsnas-16 appears in the list, force import:
sudo zpool import -f kingdezignsnas-16

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.

โ€” Pool imported but /export/kingdezignsnas-16 is missing
# Access backup files directly via the ZFS mount point:
ls /kingdezignsnas-16/Backups/NAS16/

/export/kingdezignsnas-16/ is created by OMV when it mounts the filesystem. Use /kingdezignsnas-16/ as the base path for all restore commands until OMV is fully restored.

Key differences from NAS08
AreaNAS08NAS16
Primary role Docker containers (Pi-hole, Plex, Vaultwarden, Nextcloud, NPM) Web server (Apache/PHP), databases (MariaDB), Webmin admin
What's backed up beyond /etc + OMV Docker Compose files, Pi-hole data, Plex config/metadata Apache vhosts, PHP config, MariaDB dumps, Webmin config
Website files N/A Intentionally excluded โ€” stored on NAS drives, covered by redundancy
Database backup None (no databases) Full mysqldump of all user databases, .sql.gz per database
Backup destination /export/kingdezigns-all/Backups/NAS08/ /export/kingdezignsnas-16/Backups/NAS16/
ZFS pool name kingdezignsnas kingdezignsnas-16 (assumed โ€” verify with sudo zpool list)
Recovery phases 9 phases, 34 steps 10 phases, 40 steps
Notes & assumptions to verify
โš  Verify these before first run

The script was written based on information provided and follows Raspberry Pi OS / Debian conventions. Verify the following on NAS16 before treating any backup as production-ready.

ItemAssumed valueHow to verify
ZFS pool name kingdezignsnas-16 sudo zpool list
Backup destination path /export/kingdezignsnas-16/Backups/NAS16/ ls /export/ โ€” confirm share name matches
MariaDB auth method Uses /etc/mysql/debian.cnf (maintenance account, no password when run as root) Run: sudo mysql --defaults-file=/etc/mysql/debian.cnf -e "SHOW DATABASES;" โ€” should work without password
PHP version(s) Auto-detected from /etc/php/*/ php -v and ls /etc/php/
Apache config location /etc/apache2/ (standard Debian) apache2 -V โ€” confirms config path
Webmin config location /etc/webmin/ ls /etc/webmin/
Network map โ€” items to update
ItemOld valueNew value
NAS16 โ€” Backup status None Automated โ€” every 3 days โ€” 30-day retention
NAS16 โ€” Backup destination None /export/kingdezignsnas-16/Backups/NAS16/
NAS16 โ€” Backup script None /usr/scripts/omv/nas16-backup.sh
NAS16 โ€” PCIe requirement not documented dtparam=pciex1 + dtparam=pciex1_gen=3 required in /boot/firmware/config.txt on fresh OS
NAS16 โ€” Web stack not documented Apache ยท PHP ยท MariaDB ยท Webmin ยท Adminer
NAS16 โ€” Recovery plan None NAS16-Backup-Summary.html โ€” 40 steps across 10 phases + ZFS troubleshooting