UniFi UNAS-Pro Master Backup Strategy: Native Rsync Daemon (Pull) Architecture#

This document defines the complete operational standard, architecture, schedule matrix, node-by-node configuration reference, and disaster recovery procedures for backing up all shared data from the master UniFi UNAS-Pro NAS (10.1.2.2) across the fleet of 5 TrueNAS SCALE storage nodes (HP1, HP2, HP3, HP6, HP7). It is designed to be sufficient to fully reconstruct the entire setup from scratch.

The former HP7TrueNAS node (10.1.1.17) is now HP6TrueNAS. The storage dataset, SMB shares, and backup script have been renamed to the HP6 identifiers.

Antigravity Chat: agy –conversation=4c0c9b6d-2722-4fd6-a4aa-638c75ab46f4


1. Executive Summary & Architecture Overview#

Historically, backups were driven by UniFi Drive UI-managed SMB (Push) tasks that wrote into auto-generated wrapper folders (such as UNAS Pro_HP1).

The current production architecture shifts 100% of backups to a Native Rsync Daemon (Pull) model:

               ┌──────────────────────────────────────────────────────────┐
               │              UNAS-Pro Master NAS (10.1.2.2)              │
               │        Exposes 12 Shared Rsync Modules over SSH/TCP      │
               └────────────────────────────┬─────────────────────────────┘
                                            │
         ┌──────────────────┬───────────────┼───────────────┬──────────────────┐
         │ (Min :00)        │ (Min :20)     │ (Min :50)     │ (Min :30)        │ (Min :15)
         ▼                  ▼               ▼               ▼                  ▼
  ┌──────────────┐   ┌──────────────┐┌──────────────┐┌──────────────┐   ┌──────────────┐
  │ HP1 TrueNAS  │   │ HP2 TrueNAS  ││ HP3 TrueNAS  ││ HP6 TrueNAS  │   │ HP7 TrueNAS  │
  │ 10.1.2.201   │   │ 10.1.2.212   ││ 10.1.2.213   ││ 10.1.1.16    │   │ 10.1.2.207   │
  └──────────────┘   └──────────────┘└──────────────┘└──────────────┘   └──────────────┘

Key Architectural Principles:#

  1. Pull Model: Remote TrueNAS nodes initiate SSH/Rsync pulls. UNAS-Pro operates purely as a read-only source, preventing unauthorized write modifications to master data.
  2. Dataset Root Landing: Backups land directly at the root of target ZFS datasets without nested SMB wrapper directories (UNAS Pro_HP*).
  3. Staggered 24/7 Hourly Schedules: Backups run every hour, 24 hours a day, 7 days a week. Each server is assigned a distinct minute offset to eliminate I/O and network saturation on the UNAS-Pro.
  4. Git-Managed Standalone Scripts: Backup logic is maintained in a central Git repository, auto-mirrored to UNAS-Pro via Git post-commit hook, and synced to each TrueNAS node via Rsync.
  5. Native GMail Notifications: Execution logs are stored locally, pruned automatically after 30 days, and emailed via TrueNAS SCALE’s native middleware GMail OAuth integration (sudo midclt call mail.send).

2. Fleet Production Schedule Matrix#

Node IP Address ZFS Pool Target Dataset Path Modules Pulled Cron Schedule Log Path
HP1 10.1.2.201 RaidZ1SSDPool8TB /mnt/RaidZ1SSDPool8TB/HP1UNASBackup/ Books, Photos, Nadine, [Immich](Immich.md), Musique, Software, HomesDSM, Documents, Downloads, GoogleCloudSync 0 * * * * /mnt/homes/unas_backup/
HP2 10.1.2.212 Raid0SSDPool3TB /mnt/Raid0SSDPool3TB/HP2UNASBackup/ Books, Immich, Nadine, Photos, Musique, Software, HomesDSM, Documents 20 * * * * /mnt/Homes/unas_backup/unas_backup/
HP3 10.1.2.213 Medias /mnt/Medias/HP7Medias/ Films, TVSeries 50 * * * * /mnt/Homes/unas_backup/unas_backup/
HP6 10.1.1.16 Stripe4TB /mnt/Stripe4TB/HP6UNASBackup/ Books, Photos, Nadine, Immich, Musique, Software, HomesDSM, Documents, GoogleCloudSync 10 * * * * /mnt/Stripe4TB/Homes/unas_backup/
HP7 10.1.2.207 RaidZ1SSDPool8TB /mnt/RaidZ1SSDPool8TB/HP7UNASBackup/; /mnt/Medias/HP7Medias/ Books, Photos, Nadine, Immich, Musique, Software, HomesDSM, Documents, GoogleCloudSync, Films, TVSeries 15 * * * * /mnt/homes/unas_backup/

3. UNAS-Pro Source Configuration#

The master UniFi UNAS-Pro (10.1.2.2) exposes shared folders as Rsync modules over SSH (TCP 22). The following must be configured in the UniFi Drive Web UI.

⚙️ Step 1 — Enable Rsync Server (UniFi Drive Web UI)#

  1. Open UniFi Drive Web UI at https://10.1.2.2.
  2. Navigate to Settings > Services / Rsync.
  3. Toggle Enable Rsync Server to ON.

⚙️ Step 2 — Expose Shared Folders as Rsync Modules#

  1. Navigate to UniFi Drive > Shared Folders / Drives.
  2. Edit each shared folder and enable Expose as Rsync Module.
  3. Exposed modules (12 total):
    • Core Data: Books, Documents, Downloads, GoogleCloudSync, HomesDSM, Immich, Musique, Nadine, Photos, Software
    • Media: Films, TVSeries

⚙️ Step 3 — Add TrueNAS SSH Public Keys to UNAS-Pro#

Each TrueNAS node authenticates to UNAS-Pro using passwordless SSH keypairs. No local OS user needs to be created on UNAS-Pro. Keys are added to /root/.ssh/authorized_keys.

SSH into UNAS-Pro as root:

ssh root@10.1.2.2

Append each TrueNAS node’s public key:

echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICa5Yy936hW6B/YvX9pU09jN unas_backup@HP1TrueNAS" >> /root/.ssh/authorized_keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOB37h2+l37HNm5Cykgb7jANgFTv7uzZpYSOA8CFXggy unas_backup@HP2TrueNAS" >> /root/.ssh/authorized_keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6N9s11W7KkX0w4q5N+z7M9 unas_backup@HP3TrueNAS" >> /root/.ssh/authorized_keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAtWUhNjo/n4Z9fye+5SX/EwaS/+ws9UPUIY8ATc8rQ unas_backup@HP6TrueNAS" >> /root/.ssh/authorized_keys
echo "sh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9Xa/Eicgg+BOpXZoa1J1VLXHn4Mu+j4TA6H/EMPJiw unas_backup@HP6TrueNAS" >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

✅ Step 4 — Verify Rsync Modules Are Visible from a TrueNAS Node#

From any TrueNAS node SSH session (as unas_backup), run:

sudo -u unas_backup rsync -e "ssh -i /mnt/homes/unas_backup/.ssh/id_ed25519 -o StrictHostKeyChecking=no" root@10.1.2.2::

Expected output: a list of all 12 exposed modules.

3.1 Immich Photo Ingress Mounts#

The Immich host 10.1.2.231 and the backup-capable Linux host 10.1.2.202 mount the live photo destination and the Synology source for the one-way Photos push:

Host path Remote share Role
/mnt/Photos //10.1.2.2/Photos UNAS-Pro photo library; consumed by Immich on 10.1.2.231 and used as the sync destination on both hosts
/mnt/HP1Photos //10.1.2.221/HP1Photos Read-only Synology source for the one-way photo sync on both hosts

The Synology source mount /mnt/HP1Photos was changed to read-only on 2026-09-10 on both hosts. The UNAS-Pro /mnt/Photos mount remains read-write. The pushphotos alias executes the shared /mnt/Software/Software/Scripts/Linux/HP1_Synology_Photos_Push.sh script from either host. This ingress path is separate from the TrueNAS HPX_UNAS_Pull_Backup.sh scripts, which continue to provide UNAS-Pro-to-TrueNAS backups.

3.2 Synology Photos to UNAS-Pro Push#

The authoritative photo workflow is a one-way push from the Synology VM to the UNAS-Pro:

HP1SynologyDSM VM (10.1.2.221)
        │  HP1Photos SMB share, mounted read-only
        ▼
Linux sync host (HP1GPU 10.1.2.231 or HP1Docker 10.1.2.202)
        │  rsync over local SMB mounts
        ▼
UNAS-Pro (10.1.2.2) — Photos shared folder
        │
        ▼
Immich external library on HP1GPU

Linux Sync Hosts#

Both Linux hosts use the same shared script and aliases:

Host Source mount Destination mount Command
HP1GPU (10.1.2.231) /mnt/HP1Photos /mnt/Photos pushphotos
HP1Docker (10.1.2.202) /mnt/HP1Photos /mnt/Photos pushphotos

The script is stored on the UNAS-Pro Software share and is available at:

/mnt/Software/Software/Scripts/Linux/HP1_Synology_Photos_Push.sh

Synchronization Rules#

  • Synchronization is always Synology → UNAS-Pro.
  • The Synology HP1Photos share is mounted read-only on both Linux hosts.
  • The UNAS-Pro Photos share is mounted read-write because it is the rsync destination.
  • New and changed files are copied to UNAS-Pro.
  • Files deleted from Synology are deleted from the UNAS-Pro Photos share on the next run.
  • Synology metadata and system directories are excluded: #snapshot/, #recycle/, .stfolder/, .unas_photos_connected, .unas_connected, @eaDir/, @tmp/, @sharesnap/, .DS_Store, Thumbs.db, and desktop.ini.
  • The script prints copied, updated, and deleted files, writes a local log, and sends a completion or failure email.

Run the operation manually from either Linux host with:

pushphotos

The Linux hosts are the supported execution points for this workflow because they complete the SMB-to-SMB comparison efficiently and keep the process independent of the Immich container lifecycle.


4. Git Repository & Script Management#

Backup scripts are version-controlled and automatically distributed to UNAS-Pro via a Git post-commit hook.

Repository Setup (Mac Studio Workstation)#

Repository location: /Users/marc/Scripts/
Remote: git@github.com:marcoue/Scripts.git

Clone on a new Mac Studio:

git clone git@github.com:marcoue/Scripts.git /Users/marc/Scripts

Script locations:

/Users/marc/Scripts/TrueNAS/
├── HP1_UNAS_Pull_Backup.sh
├── HP2_UNAS_Pull_Backup.sh
├── HP3_UNAS_Pull_Backup.sh
├── HP6_UNAS_Pull_Backup.sh
└── HP8_UNAS_Pull_Backup.sh

Git Post-Commit Hook (Auto-Mirror to UNAS-Pro)#

The hook is located at /Users/marc/Scripts/.git/hooks/post-commit. It automatically mirrors the TrueNAS/ scripts directory to UNAS-Pro after every commit.

To recreate the hook on a new workstation:

cat > /Users/marc/Scripts/.git/hooks/post-commit << 'EOF'
#!/bin/bash
rsync -av /Users/marc/Scripts/TrueNAS/ root@10.1.2.2:/Volume1/Software/Software/Scripts/TrueNAS/
EOF
chmod +x /Users/marc/Scripts/.git/hooks/post-commit

Scripts on UNAS-Pro (mirror destination):

/Volumes/Software/Software/Scripts/TrueNAS/
(Exposed via Rsync as: root@10.1.2.2::Software/Software/Scripts/TrueNAS/)
Node Script Path on Node Auto-Sync via Backup
HP1 /mnt/RaidZ1SSDPool8TB/HP1UNASBackup/Software/Software/Scripts/TrueNAS/HP1_UNAS_Pull_Backup.sh Yes (Pulls Software module)
HP2 /mnt/Raid0SSDPool3TB/HP2UNASBackup/Software/Software/Scripts/TrueNAS/HP2_UNAS_Pull_Backup.sh Yes (Pulls Software module)
HP3 /mnt/Homes/unas_backup/unas_backup/scripts/HP3_UNAS_Pull_Backup.sh Self-Updates at start of script
HP6 /mnt/Stripe4TB/HP6UNASBackup/Software/Software/Scripts/TrueNAS/HP6_UNAS_Pull_Backup.sh Yes (Pulls Software module)
HP7 /mnt/RaidZ1SSDPool8TB/HP7UNASBackup/Software/Software/Scripts/TrueNAS/HP8_UNAS_Pull_Backup.sh Yes (Pulls Software module)

The HP7 media dataset is Medias/HP7Medias. The HP7 pull job still uses the legacy script filename HP8_UNAS_Pull_Backup.sh.

HP3 Script Self-Sync Exception: Nodes HP1, HP2, HP6, and HP7 pull the Software module during their main backup payload, which automatically updates their copy of HPX_UNAS_Pull_Backup.sh from UNAS-Pro. Because HP3 only backs up media modules (Films and TVSeries), it does not pull the Software dataset as part of its backup payload. Instead, HP3_UNAS_Pull_Backup.sh includes a 1-line self-update command at the top of the script that explicitly pulls its latest version from root@10.1.2.2::Software/Software/Scripts/TrueNAS/HP3_UNAS_Pull_Backup.sh into /mnt/Homes/unas_backup/unas_backup/scripts/HP3_UNAS_Pull_Backup.sh before running the media sync.

Standard Backup Script Blueprint#

Every node’s backup script follows these standards:

#!/usr/bin/env bash
set -euo pipefail

KEY="/mnt/homes/unas_backup/.ssh/id_ed25519"       # SSH private key path
LOG_DIR="/mnt/homes/unas_backup"                    # Log directory
DEST_DIR="/mnt/<POOL>/<DATASET>"                    # Backup destination
TIMESTAMP="$(date +%Y-%m-%d_%H-%M)"
LOG_FILE="${LOG_DIR}/${TIMESTAMP}_unas_backup.log"
MODULES=("Module1" "Module2")                       # Rsync modules to pull

mkdir -p "${LOG_DIR}"

{
  echo "=== HPX UNAS Pull Backup Started: ${TIMESTAMP} ==="
  for mod in "${MODULES[@]}"; do
    echo "--> Pulling module: ${mod}"
    rsync -av --no-o --no-g --delete --backup \
      --backup-dir="${DEST_DIR}/$(date +%Y-%m-%d)_Rsync_deleted" \
      -e "ssh -i ${KEY} -o StrictHostKeyChecking=no" \
      "root@10.1.2.2::${mod}/" "${DEST_DIR}/${mod}/"
  done
  echo "=== Pruning logs older than 30 days ==="
  find "${LOG_DIR}" -maxdepth 1 -type f -name "*_unas_backup.log" -mtime +30 -delete
  echo "=== Backup Complete: $(date +%Y-%m-%d_%H-%M) ==="
} > "${LOG_FILE}" 2>&1

if [ $? -eq 0 ]; then
  sudo midclt call mail.send '{"subject": "SUCCESS: HPX UNAS Backup", "text": "HPX UNAS Backup completed successfully.", "to": ["proxmox.app@gmail.com"]}'
else
  sudo midclt call mail.send '{"subject": "FAILURE: HPX UNAS Backup", "text": "HPX UNAS Backup failed.", "to": ["proxmox.app@gmail.com"]}'
fi

5. Per-Node Configuration Reference#

Node IP SSH User Key Path Log Directory unas_backup User ID Symlink Requirement
HP1 10.1.2.201 /mnt/homes/unas_backup/.ssh/id_ed25519 /mnt/homes/unas_backup/ 84 Native ZFS /mnt/homes/
HP2 10.1.2.212 /mnt/Homes/unas_backup/unas_backup/.ssh/id_ed25519 /mnt/Homes/unas_backup/unas_backup/ 74 Native ZFS /mnt/Homes/
HP3 10.1.2.213 /mnt/Homes/unas_backup/unas_backup/.ssh/id_ed25519 /mnt/Homes/unas_backup/unas_backup/ 78 Native ZFS /mnt/Homes/
HP6 10.1.1.16 /mnt/homes/unas_backup/.ssh/id_ed25519 /mnt/Stripe4TB/Homes/unas_backup/ 76 ln -s /mnt/Stripe4TB/Homes /mnt/homes
HP7 10.1.2.207 /mnt/homes/unas_backup/.ssh/id_ed25519 /mnt/homes/unas_backup/ 78 ln -s "/mnt/Apps - Homes/Homes" /mnt/homes

Why Symlinks Are Required for HP6 and HP7:

  • HP1: HP1’s home directory pool is created at /mnt/homes/ without spaces or pool-name prefixes. No symlink is needed.
  • HP6: HP6’s home directory dataset is stored at /mnt/Stripe4TB/Homes/. A symlink (/mnt/homes -> /mnt/Stripe4TB/Homes) was created to standardize the path.
  • HP7: HP7’s home directory pool is named Apps - Homes (/mnt/Apps - Homes/Homes/). Because the pool name contains spaces, unquoted -e "ssh -i $KEY" commands inside rsync fail when parsing the path. The symlink /mnt/homes -> /mnt/Apps - Homes/Homes resolves the path cleanly without spaces.

Per-Node TrueNAS Cron Job Registry#

Node Cron Job ID Description User Schedule Command
HP1 6 UNAS-Pro HP1 Backup Pull (Script Method) unas_backup 0 * * * * bash /mnt/RaidZ1SSDPool8TB/HP1UNASBackup/Software/Software/Scripts/TrueNAS/HP1_UNAS_Pull_Backup.sh
HP2 1 UNAS-Pro HP2 Backup Pull (Script Method) unas_backup 20 * * * * bash /mnt/Raid0SSDPool3TB/HP2UNASBackup/Software/Software/Scripts/TrueNAS/HP2_UNAS_Pull_Backup.sh
HP3 2 UNAS-Pro HP7Medias Backup Pull (Script Method) unas_backup 50 * * * * bash /mnt/Homes/unas_backup/unas_backup/scripts/HP3_UNAS_Pull_Backup.sh
HP6 5 UNAS-Pro HP6 Backup Pull (Script Method; disabled) unas_backup 10 * * * * bash /mnt/Stripe4TB/HP6UNASBackup/Software/Software/Scripts/TrueNAS/HP6_UNAS_Pull_Backup.sh
HP7 — UNAS-Pro HP7 Backup Pull (Script Method; legacy script filename) unas_backup 15 * * * * bash /mnt/RaidZ1SSDPool8TB/HP7UNASBackup/Software/Software/Scripts/TrueNAS/HP8_UNAS_Pull_Backup.sh

6. Security & Permission Standard#

6.1 Service Account Setup (Per TrueNAS Node)#

  1. Create unas_backup user in TrueNAS Web UI (Credentials > Local Users > Add):

    • Username: unas_backup
    • Enable Create Home Directory
    • Leave all access toggles (SMB, TrueNAS, SSH) unchecked
  2. Generate SSH keypair on the node:

    sudo chown -R unas_backup:unas_backup /mnt/homes/unas_backup
    sudo -u unas_backup mkdir -p /mnt/homes/unas_backup/.ssh
    sudo -u unas_backup chmod 700 /mnt/homes/unas_backup/.ssh
    sudo -u unas_backup ssh-keygen -t ed25519 -N '' -f /mnt/homes/unas_backup/.ssh/id_ed25519
    sudo -u unas_backup cat /mnt/homes/unas_backup/.ssh/id_ed25519.pub
  3. Grant passwordless sudo via TrueNAS middleware (NOT via /etc/sudoers — TrueNAS resets it on updates):

    # First get the user ID
    sudo midclt call user.query '[["username", "=", "unas_backup"]]'
    # Then grant sudo
    sudo midclt call user.update <USER_ID> '{"sudo_commands_nopasswd": ["ALL"]}'
  4. Set ZFS dataset permissions:

    sudo zfs set aclmode=passthrough <POOL>/<DATASET>
    sudo chown -R unas_backup:unas_backup /mnt/<POOL>/<DATASET>/
    sudo chmod -R 777 /mnt/<POOL>/<DATASET>/

6.2 TrueNAS API Key Setup (for MCP / AI Agent Access)#

Each TrueNAS node requires an API key stored in 1Password for AI agent access via the MCP server fleet.

  1. Create API key in TrueNAS Web UI: System Settings > API Keys > Add.
    • Name: antigravity-cli
  2. Store in 1Password: Save in vault Homelab, item antigravity-cli, field HPX_TRUENAS_API_KEY.
  3. Add to MCP config: Update ~/.mcp-config/config.json with a truenas-hpX entry using https://10.1.X.X (always HTTPS — HTTP will auto-revoke the API key).
  4. Deploy: Run cd ~/.mcp-config && ./apply.py.

6.3 GMail OAuth Email Notification Setup#

Each TrueNAS node sends backup status emails via GMail OAuth to proxmox.app@gmail.com.

  1. In TrueNAS Web UI, navigate to System Settings > General > Email.
  2. Set Send Mail Method to GMail OAuth.
  3. Click Log In to GMail and authenticate with proxmox.app@gmail.com.
  4. Click Send Test Email to verify delivery.

GMail OAuth tokens expire periodically. If backup emails stop arriving, re-authenticate via TrueNAS Web UI > System Settings > General > Email.

6.4 ZFS Periodic Snapshot Protection#

Each node maintains automatic ZFS snapshots as a safety net against accidental deletions or ransomware:

Node Dataset Snapshot Schedule Retention
HP1 RaidZ1SSDPool8TB/HP1UNASBackup Daily at 00:00 4 weeks (28 days)
HP2 Raid0SSDPool3TB/HP2UNASBackup Daily at 18:29 2 days
HP3 Medias/HP7Medias Daily at 09:55 4 weeks (28 days)
HP6 Stripe4TB/HP6UNASBackup Daily 7 days
HP7 RaidZ1SSDPool8TB/HP7UNASBackup Daily 7 days

7. Log Monitoring Reference#

Logs are named YYYY-MM-DD_HH-MM_unas_backup.log and auto-pruned after 30 days.

Node SSH Command to View Latest Log
HP1 ssh marcoue@10.1.2.201 "sudo ls -t /mnt/homes/unas_backup/*_unas_backup.log | head -n 1 | xargs sudo tail -n 50"
HP2 ssh marcoue@10.1.2.212 "sudo ls -t /mnt/Homes/unas_backup/unas_backup/*_unas_backup.log | head -n 1 | xargs sudo tail -n 50"
HP3 ssh marcoue@10.1.2.213 "sudo ls -t /mnt/Homes/unas_backup/unas_backup/*_unas_backup.log | head -n 1 | xargs sudo tail -n 50"
HP6 ssh marcoue@10.1.1.16 "sudo ls -t /mnt/Stripe4TB/Homes/unas_backup/*_unas_backup.log | head -n 1 | xargs sudo tail -n 50"
HP7 ssh marcoue@10.1.2.207 "sudo ls -t /mnt/homes/unas_backup/*_unas_backup.log | head -n 1 | xargs sudo tail -n 50"

8. Disaster Recovery — Complete Rebuild Procedures#

8.1 Rebuild a Single TrueNAS Node from Scratch#

Follow these steps for any node. Replace HPX, 10.1.X.X, <POOL>, <DATASET>, <MINUTE> with node-specific values from the tables above.

Step 1 — Create unas_backup service account:

# Via TrueNAS Web UI: Credentials > Local Users > Add
# Username: unas_backup, Enable Home Directory, no other access

Step 2 — Grant passwordless sudo:

USER_ID=$(sudo midclt call user.query '[["username", "=", "unas_backup"]]' | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])")
sudo midclt call user.update ${USER_ID} '{"sudo_commands_nopasswd": ["ALL"]}'

Step 3 — Generate SSH keypair:

sudo -u unas_backup ssh-keygen -t ed25519 -N '' -f /mnt/homes/unas_backup/.ssh/id_ed25519
sudo -u unas_backup cat /mnt/homes/unas_backup/.ssh/id_ed25519.pub
# Copy output — needed for Step 4

Step 4 — Register public key on UNAS-Pro:

ssh root@10.1.2.2 "echo '<PASTE_PUBLIC_KEY_HERE>' >> /root/.ssh/authorized_keys"

Step 5 — Verify SSH & Rsync connection:

sudo -u unas_backup rsync -e "ssh -i /mnt/homes/unas_backup/.ssh/id_ed25519 -o StrictHostKeyChecking=no" root@10.1.2.2::
# Should list all 12 modules

Step 6 — Set ZFS dataset permissions:

sudo zfs set aclmode=passthrough <POOL>/<DATASET>
sudo chown -R unas_backup:unas_backup /mnt/<POOL>/<DATASET>/
sudo chmod -R 777 /mnt/<POOL>/<DATASET>/

Step 7 — Sync backup script from UNAS-Pro:

sudo -u unas_backup rsync -av \
  -e "ssh -i /mnt/homes/unas_backup/.ssh/id_ed25519 -o StrictHostKeyChecking=no" \
  "root@10.1.2.2::Software/Software/Scripts/TrueNAS/HPX_UNAS_Pull_Backup.sh" \
  "/mnt/<POOL>/<DATASET>/Software/Software/Scripts/TrueNAS/HPX_UNAS_Pull_Backup.sh"
sudo chmod +x /mnt/<POOL>/<DATASET>/Software/Software/Scripts/TrueNAS/HPX_UNAS_Pull_Backup.sh

Step 8 — Register Cron Job via TrueNAS middleware:

sudo midclt call cronjob.create '{
  "description": "UNAS-Pro HPX Backup Pull (Script Method)",
  "user": "unas_backup",
  "command": "bash /mnt/<POOL>/<DATASET>/Software/Software/Scripts/TrueNAS/HPX_UNAS_Pull_Backup.sh",
  "schedule": {"minute": "<MINUTE>", "hour": "*", "dom": "*", "month": "*", "dow": "*"},
  "enabled": true,
  "stdout": true,
  "stderr": false
}'

Step 9 — Configure GMail OAuth:

  • Go to TrueNAS Web UI > System Settings > General > Email.
  • Set Send Mail Method to GMail OAuth, authenticate with proxmox.app@gmail.com.

Step 10 — Test run:

sudo midclt call cronjob.run <CRON_JOB_ID>
# Then verify log and email

8.2 Rebuild UNAS-Pro from Scratch#

If the UNAS-Pro itself is wiped or replaced:

  1. Enable Rsync Server: UniFi Drive Web UI > Settings > Services / Rsync > ON.
  2. Re-expose all 12 modules: UniFi Drive > Shared Folders — enable Expose as Rsync Module for all folders.
  3. Re-add all SSH public keys to /root/.ssh/authorized_keys (see Section 3, Step 3).
  4. Verify connectivity from each TrueNAS node using the test command in Section 3, Step 4.

All backup data resides safely on the TrueNAS nodes during a UNAS-Pro outage. The UNAS-Pro is the source, not the backup destination. A UNAS-Pro rebuild only requires restoring SSH keys and Rsync module configuration — no data recovery is needed from backups.


8.3 Rebuild Mac Studio Workstation (Script Management)#

If the Mac Studio workstation is replaced:

  1. Clone the scripts repository:
    git clone git@github.com:marcoue/Scripts.git /Users/marc/Scripts
  2. Recreate the Git post-commit hook:
    cat > /Users/marc/Scripts/.git/hooks/post-commit << 'EOF'
    #!/bin/bash
    rsync -av /Users/marc/Scripts/TrueNAS/ root@10.1.2.2:/Volume1/Software/Software/Scripts/TrueNAS/
    EOF
    chmod +x /Users/marc/Scripts/.git/hooks/post-commit
  3. Restore MCP configuration: Clone ~/.mcp-config from its Git repository, restore 1Password credentials, and run ./apply.py.