Storage intermediate ⏱ 60 minutes

TrueNAS: Complete Storage Setup and Management Guide

Build enterprise-grade storage for your homelab. ZFS, snapshots, replication, and network shares.

By homelabbing.io • 2025-12-16
#truenas#storage#zfs#nas#backup

A comprehensive guide to deploying and managing TrueNAS SCALE for your homelab, from initial setup through advanced automation with AI.

Difficulty Level: Intermediate Estimated Time: 60 minutes Last Updated: 2025-12-16


Prerequisites

Before diving into TrueNAS, ensure you have:

Required Knowledge

  • Basic networking concepts (IP addresses, subnetting, Ethernet)
  • Understanding of RAID and storage redundancy
  • Basic Linux/Unix command line experience (helpful but not required)
  • Familiarity with file permissions

Hardware Requirements

Minimum Setup:

  • 2-core CPU @ 1.5 GHz or higher
  • 8 GB RAM (16 GB recommended)
  • 32-64 GB SSD for boot device
  • 4+ data drives for RAID configuration
  • Gigabit Ethernet connection

Recommended Setup:

  • 4-8 cores, modern processor (Intel 11th gen+, AMD Ryzen 5000+)
  • 16-32 GB ECC RAM
  • Mirrored SSD boot pool
  • 10 Gbps network interface (optional but beneficial)
  • UPS for power protection
  • HBA (Host Bus Adapter) for direct disk access

Software Tools

  • TrueNAS SCALE installation media (USB stick or ISO)
  • Network access and SSH capability
  • Web browser for accessing TrueNAS UI

Section 1: Understanding TrueNAS Architecture

TrueNAS CORE vs SCALE: Making the Right Choice

TrueNAS comes in two variants, each serving different needs. Understanding the differences is crucial for a successful deployment.

TrueNAS CORE (FreeBSD-Based)

TrueNAS CORE represents the mature, stable branch based on FreeBSD. It’s currently in maintenance mode with security patches only—no new features are planned.

Key Characteristics:

  • Proven, mature platform with years of stability
  • Lower resource requirements (8 GB RAM minimum)
  • Excellent performance on older hardware
  • Jails-based containerization (not Docker)
  • Uses Bhyve for virtualization

When to Choose CORE:

  • Running on hardware older than 10 years
  • Building a dedicated storage appliance
  • System has minimal RAM (under 8 GB)
  • Want proven stability over new features

TrueNAS SCALE is the modern, actively developed platform based on Debian Linux. This is the recommended choice for new deployments in 2025.

Key Characteristics:

  • Actively developed with frequent updates
  • Native Docker and containerization (v24.10+)
  • Docker Compose for app management
  • Excellent AMD/modern CPU support
  • Advanced ZFS features (expansion, improved deduplication)
  • Higher resource requirements (16GB+ RAM recommended)

Recent Major Updates (v24.10+):

  • Docker support fully integrated
  • Moved from Kubernetes to Docker Compose
  • ZFS pool expansion capability
  • Improved deduplication algorithms

When to Choose SCALE (Recommended):

  • Building a modern homelab NAS
  • Planning to run applications/containers
  • Using modern hardware (AMD Ryzen, Intel recent)
  • Need Docker support for applications
  • Want active development and new features

Quick Comparison

FeatureCORESCALE
Base OSFreeBSDDebian Linux
RAM Minimum8 GB16 GB
CPU Recommendation2+ cores4+ cores
VirtualizationBhyveKVM
ContainersJailsDocker/Compose
Development StatusSecurity patchesActive development
Recommended ForStorage-onlyMulti-purpose

Decision Made Simple: For most homelabbers in 2025, choose TrueNAS SCALE. It offers more features, better hardware support, and represents the future of TrueNAS.


Section 2: ZFS Fundamentals and Pool Design

Understanding ZFS: The Heart of TrueNAS

ZFS (Zettabyte File System) is what makes TrueNAS special. It’s a combined file system and logical volume manager that provides enterprise-grade data protection.

Why ZFS Matters:

  • Data Integrity: Every block includes checksums; corruption is detected and often auto-repaired
  • Copy-on-Write (CoW): Original data remains safe during writes; prevents corruption from power loss
  • Snapshots: Near-instantaneous, space-efficient point-in-time copies
  • Self-Healing: Redundant configurations automatically repair bit rot
  • No Data Loss Reports: Users consistently report no data loss from technical issues (only human error or theft)

Core ZFS Concepts

Pools (zpool)

A pool is the top-level container for your storage. Think of it as the foundation of your storage system.

Key Points:

  • Collections of virtual devices (vdevs)
  • Always stripes vdevs for performance
  • Maximum addressable space: 256 quadrillion zettabytes

Virtual Devices (vdevs)

Vdevs are the redundancy tier of a pool. They determine your RAID configuration.

Common vdev Types:

  • Single: Single disk (no redundancy) - NOT recommended
  • Mirror: 2-4+ drives with exact copies
  • RAID-Z1: Like RAID-5 (one parity block, survives 1 disk failure)
  • RAID-Z2: Like RAID-6 (two parity blocks, survives 2 disk failures)
  • RAID-Z3: Three parity blocks (survives 3 disk failures)

Datasets

Datasets are lightweight partitions that share the pool’s storage space. Think of them as flexible folders with superpowers.

Dataset Features:

  • Each has own permissions, quotas, compression settings
  • Can be nested hierarchically
  • Support independent snapshots
  • Fine-grained control over sharing

RAID-Z Levels Explained

RAID-Z1 (Like RAID-5)

Configuration: 3-6 drives recommended
Parity: One parity block distributed
Fault Tolerance: Survives ONE disk failure
Usable Capacity: (N-1) × drive_size

Example: 4 × 4TB drives
Total Raw: 16 TB
Parity: 4 TB (25%)
Usable: 12 TB

Best For: General-purpose storage, moderate redundancy needs
Risk: Vulnerable during rebuild; second drive failure = data loss
Configuration: 4-8 drives recommended
Parity: Two parity blocks distributed
Fault Tolerance: Survives TWO simultaneous disk failures
Usable Capacity: (N-2) × drive_size

Example: 4 × 4TB drives
Total Raw: 16 TB
Parity: 8 TB (50%)
Usable: 8 TB

Best For: Critical data, most homelab deployments
Benefit: Safe during rebuild; can survive second failure

RAID-Z3 (Triple Parity)

Configuration: 5+ drives recommended
Parity: Three parity blocks distributed
Fault Tolerance: Survives THREE simultaneous disk failures
Usable Capacity: (N-3) × drive_size

Example: 6 × 4TB drives
Total Raw: 24 TB
Parity: 12 TB (50%)
Usable: 12 TB

Best For: Maximum protection, enterprise-critical data

Capacity Planning Example

Let’s design a pool for a typical homelab media server:

Requirements:

  • 8 TB usable storage
  • Survive 2 simultaneous disk failures
  • Budget: ~$400 for drives

Solution: 4 × 4TB drives in RAID-Z2

Hardware: 4 × 4TB WD Red Pro drives
Total Raw Capacity: 16 TB
RAID Configuration: RAID-Z2 (2 parity drives)
Parity Overhead: 8 TB (50%)
Usable Capacity: 8 TB
Redundancy: Survives 2 disk failures
Cost: ~$400 (4 × $100/drive)

ZFS Best Practices

  1. Use whole disks: ZFS works best with complete drives
  2. Allocate sufficient RAM: Minimum 1GB per 1-2TB usable storage
  3. Separate boot from data: Install OS on separate small SSD
  4. Avoid hardware RAID: TrueNAS needs direct disk access
  5. Plan redundancy upfront: Adding redundancy later is difficult
  6. Monitor pool health: Regularly check for degraded vdevs
  7. Remember: ZFS protects against hardware failure, NOT deletion/malware

Critical Understanding: ZFS is NOT a backup strategy. It protects against hardware failure but not:

  • Accidental file deletion (use snapshots)
  • Ransomware/malware (use air-gapped backups)
  • Physical theft (use encrypted backups)
  • Complete system failure (use remote replication)

Section 3: Hardware Selection and System Design

CPU Selection

For Basic Storage:

  • Intel Celeron G4900 or AMD Ryzen 3 3100
  • Sufficient for file sharing and basic NAS functions

For Moderate Use:

  • Intel i3-10100 or AMD Ryzen 5 3600
  • Handles file sharing + light container workloads

For Advanced Use:

  • Intel i5-10400 or AMD Ryzen 5 5600X
  • Supports virtualization + containers + AI workloads

Key Considerations:

  • More clock speed > more cores for typical NAS workloads
  • VT-d/AMD-Vi support required for device pass-through
  • Modern architectures (Intel 11th gen+, AMD Ryzen 5000+) preferred

RAM Requirements

The “1GB per 1TB” Rule is Outdated

Modern approach: Size RAM based on workload intensity.

Practical RAM Sizing:

  • 8 GB: Absolute minimum; light homelab use only
  • 16 GB: Recommended standard for most homelabs (4-20TB storage)
  • 32 GB: Heavy workloads, deduplication, intensive applications
  • 64+ GB: Enterprise deployments, very large systems

ECC Memory: Strongly recommended but not required

  • Costs 10-20% more than non-ECC
  • Prevents silent data corruption
  • Requires compatible server motherboards and CPUs
  • Available in most modern server platforms

Non-ECC works but increases risk: ZFS will function with non-ECC RAM, but you lose a layer of protection against memory errors that could corrupt data.

Storage Controllers: Critical Decision

The Golden Rule: TrueNAS REQUIRES direct disk access.

Recommended: HBA (Host Bus Adapter)

  • Passes drives through without RAID processing
  • Examples: LSI MegaRAID 9211-8i (IT mode), Adaptec 6805H
  • Cost: $50-150 used, $200-400 new
  • Setup: Simple, straightforward

Alternative: Motherboard SATA/SAS

  • Direct connection without controller
  • Works perfectly for smaller deployments
  • Limitation: Usually 6-8 SATA ports max

AVOID: Hardware RAID Controllers

  • Must be in pass-through/IT mode or disabled
  • Hardware RAID hides drive information from ZFS
  • Result: Cannot identify failing drives, loss of RAID parity info

Boot Device Options

Option 1: USB Stick (Budget)

Capacity: 16GB recommended
Cost: $10-15
Lifespan: Can fail; keep backup
Use Case: Testing, temporary deployments

Option 2: SSD (Recommended)

Capacity: 32-64GB SATA SSD
Cost: $30-80
Lifespan: 5-10 years
Use Case: Standard production deployments
Setup: Can be mirrored for redundancy

Option 3: M.2 SSD (Modern)

Capacity: 32-64GB NVMe M.2
Cost: $30-100
Lifespan: 5-10 years
Use Case: Modern systems, high performance

Critical Note: Do NOT use boot device for data storage—reserve it exclusively for the OS.

Power Protection: Non-Negotiable

UPS (Uninterruptible Power Supply) is CRITICAL

Without a UPS, unexpected power loss can:

  • Corrupt in-flight writes
  • Damage ZFS pools
  • Cause boot device failure
  • Lead to data loss

UPS Sizing:

  • 500-800VA for typical homelab NAS
  • USB or network connection for automated shutdown
  • Integration with TrueNAS via NUT (Network UPS Tools)

Budget: $150-400 for quality UPS with automatic shutdown

Example System Build: Budget Homelab NAS

Goal: 8TB usable storage, 2-disk redundancy, $1,500 budget

Component Breakdown:

CPU: AMD Ryzen 5 3600 - $150
  - 6 cores, 12 threads
  - Excellent single-thread performance
  - Good power efficiency

Motherboard: ASRock B450M Pro4 - $100
  - Micro-ATX form factor
  - 6 SATA ports
  - Dual M.2 slots

RAM: 16GB DDR4-3200 (2×8GB) - $60
  - Non-ECC (budget constraint)
  - Adequate for 8TB storage

Boot SSD: 64GB M.2 NVMe - $40
  - Fast boot times
  - Can add second for mirror later

Storage: 4 × 4TB WD Red Pro - $400
  - CMR drives (not SMR)
  - 5400 RPM, low power
  - 3-year warranty

Case: Fractal Design Node 804 - $120
  - Dual-chamber design
  - Supports 8+ drives
  - Good airflow

PSU: Corsair CX550M - $70
  - 550W modular PSU
  - 80+ Bronze efficiency
  - Adequate headroom

Network: Onboard Gigabit - Included

UPS: CyberPower CP1500PFCLCD - $300
  - 1500VA/900W capacity
  - Pure sine wave
  - USB management

Total: ~$1,240

Remaining budget: $260 for future expansion

Performance Expectations:

  • Sequential reads: 400-500 MB/s (Gigabit bottleneck)
  • Sequential writes: 350-450 MB/s
  • Random I/O: Sufficient for media streaming, file sharing
  • Container support: 10-15 lightweight containers

Section 4: Initial Setup and Configuration

Installation Process

Step 1: Create Installation Media

Linux/macOS:

# Download latest TrueNAS SCALE ISO
wget https://download.truenas.com/TrueNAS-SCALE-xxx.iso

# Write to USB (replace sdX with your USB device)
sudo dd if=TrueNAS-SCALE-xxx.iso of=/dev/sdX bs=4M status=progress
sync

Windows: Use Rufus or Etcher to write ISO to USB stick

Step 2: Boot and Install

  1. Insert USB stick and boot from it
  2. Select “Install/Upgrade”
  3. Choose destination disk (your boot SSD/USB)
  4. Confirm destructive action
  5. Set swap size (default is usually fine)
  6. Select UEFI boot loader (recommended for modern systems)
  7. Complete installation (5-10 minutes)
  8. Remove USB stick and reboot

Step 3: First-Boot Configuration

Access Web Interface:

1. Find TrueNAS IP from your router DHCP leases
   OR use console to view IP: ip addr show

2. Open browser: http://[your-nas-ip]

3. First login:
   Username: admin
   Password: (set on first login)

Initial Setup Wizard:

  1. Accept EULA
  2. Set strong admin password
  3. Configure timezone and date/time
  4. Set hostname (e.g., “truenas-homelab”)
  5. Configure DNS servers (1.1.1.1, 8.8.8.8)
  6. Optional: Set up email alerts

Network Configuration

Static IP (Recommended):

Navigate to: Network → Interfaces

1. Click on primary interface
2. Uncheck DHCP
3. Add static IP alias:
   IP Address: 192.168.1.100
   Netmask: 255.255.255.0

4. Set Gateway: Network → Global Configuration
   IPv4 Gateway: 192.168.1.1

5. Set DNS: Network → Global Configuration
   Nameserver 1: 1.1.1.1
   Nameserver 2: 8.8.8.8

6. Apply changes (Test first!)

Important: Use “Test” button before applying network changes to avoid lockout!

Security Hardening

Essential Security Steps:

  1. Enable HTTPS (automatic self-signed certificate):
System → General Settings → GUI Settings
- UI Certificate: Choose or create self-signed cert
- UI HTTPS Port: 443
- Enable HTTPS
  1. Configure SSH (if remote access needed):
System → Services → SSH
- Enable service
- TCP Port: 22 (or custom port for security)
- Login as Root: Disabled (recommended)
- Password Auth: Enabled initially, switch to keys later
  1. Set Up Alert Services:
System → Alert Services
Add notification method:
- Email (SMTP)
- Slack webhook
- Custom webhook
- PagerDuty
  1. Configure Alerts:
System → Alert Settings
Set thresholds:
- Pool capacity warning: 80%
- Pool capacity critical: 90%
- Temperature warning: 60°C
- SMART errors: Immediate alert

Section 5: Pool and Dataset Management

Creating Your First Pool

Planning Phase: Before clicking “Create Pool,” decide:

  1. Redundancy level (RAID-Z1, Z2, or Z3)
  2. Pool name (simple, lowercase: tank, storage, media)
  3. Hot spare configuration
  4. Encryption requirements

Creation Process:

Navigate to: Storage → Pools → Create Pool

Step 1: Pool Manager
- Name: tank
- Encryption: Optional (can encrypt individual datasets)

Step 2: Data VDev Configuration
- Layout: RAID-Z2 (recommended)
- Width: 4 disks
- Select your 4 data drives
- Force: Only if necessary (usually not needed)

Step 3: Optional VDevs
Log (ZIL):
  - Add 50-100GB SSD if you have one
  - Improves sync write performance
  - Beneficial for iSCSI, NFS, databases

Hot Spare:
  - Add 1 additional drive of same size
  - Automatically replaces failed drive
  - Begins re-silvering immediately

Step 4: Review and Create
- Verify all settings
- Double-check drive selection
- Click "Create" (irreversible!)

Result: Pool created with 8TB usable (4×4TB in RAID-Z2)

Verification:

Storage → Pools → tank
Check status: ONLINE (healthy green)
Available space: ~8TB

Dataset Organization Strategy

Recommended Hierarchical Structure:

tank (main pool)
├── storage (general file storage)
│   ├── media (shared media library)
│   ├── documents (shared documents)
│   └── archives (cold storage, infrequent access)
├── apps (application storage)
│   ├── docker (docker container volumes)
│   ├── databases (database storage)
│   └── vms (virtual machine storage)
├── backups (backup destinations)
│   ├── local (local snapshots/replicas)
│   └── external (replicated to external NAS)
└── home (user home directories)
    ├── alice
    └── bob

Benefits:

  • Clear organization and purpose
  • Easier management and troubleshooting
  • Granular control over permissions
  • Flexible snapshot policies per dataset
  • Simple replication of entire branches

Creating Datasets

Example: Media Dataset

Navigate to: Storage → Datasets → Add Dataset

Configuration:
Name: media
Parent: tank/storage
Type: Filesystem

Advanced Options:
Compression: lz4 (recommended, fast with good ratio)
Deduplication: Off (unless you have 32GB+ RAM)
Quota: 5 TB (hard limit)
Reserved: 1 TB (minimum guaranteed space)
Record Size: 128K (good for media files)

Preset: Generic (or Multiprotocol if sharing via SMB+NFS)

Permissions:
ACL Type: POSIX (for NFS) or NFSv4 (for SMB)
User: media
Group: media
Permissions: 755 (rwxr-xr-x)

Click "Save"

Example: Docker Dataset

Navigate to: Storage → Datasets → Add Dataset

Configuration:
Name: docker
Parent: tank/apps
Type: Filesystem

Advanced Options:
Compression: lz4
Deduplication: Off
Quota: 2 TB
Reserved: 500 GB
Record Size: 128K

Preset: Apps (optimized for application storage)

Permissions:
User: root
Group: docker
Permissions: 755

Click "Save"

Dataset Compression Explained

lz4 (Recommended Default):

Speed: Very fast (minimal CPU impact)
Ratio: Moderate (typically 1.2-1.5x)
Best For: All general-purpose datasets
CPU Cost: <5% overhead

gzip (High Compression):

Speed: Slower (significant CPU impact)
Ratio: High (typically 2-3x)
Best For: Cold storage, archives
CPU Cost: 15-30% overhead
Levels: gzip-1 (faster) to gzip-9 (max compression)

zstd (Balanced):

Speed: Moderate
Ratio: Good (typically 1.5-2x)
Best For: Modern systems, balanced workloads
CPU Cost: 10-15% overhead
Note: Newer algorithm, emerging standard

Off (No Compression):

Use Case: Pre-compressed data (video, images, archives)
Use Case: Maximum performance required
Benefit: No CPU overhead
Downside: No space savings

Dataset Encryption

When to Use Encryption:

  • Sensitive personal data (documents, photos)
  • Compliance requirements (HIPAA, GDPR)
  • External backup destinations
  • Datasets accessible over untrusted networks

Creating Encrypted Dataset:

Storage → Datasets → Add Dataset

Name: documents-encrypted
Parent: tank/storage

Encryption Options:
Encryption: Yes
Encryption Type: Key (recommended) or Passphrase
Generate Key: Auto-generate (save the key!)
Algorithm: AES-256-GCM (default, strong)

Important: Download and securely store the encryption key!
Without the key, data is PERMANENTLY INACCESSIBLE.

Performance Impact: 5-10% CPU overhead with modern processors supporting AES-NI.

Quota and Reservation Management

Quotas: Hard limits that cannot be exceeded

Example Use Case:

Dataset: tank/storage/media
Purpose: Prevent media library from consuming all space
Quota: 5 TB (hard limit)

Result:
- Media library can grow to 5TB
- Cannot exceed 5TB even if pool has more space
- Protects other datasets from starvation

Reservations: Minimum guaranteed space

Example Use Case:

Dataset: tank/apps/databases
Purpose: Ensure database always has space
Reserved: 1 TB (minimum guaranteed)

Result:
- Database always has 1TB available
- Other datasets cannot use this space
- Critical for production databases

Combined Example:

Dataset: tank/apps/docker
Pool Size: 8 TB total
Quota: 3 TB (max Docker can use)
Reserved: 1 TB (min guaranteed for Docker)

Available for Docker: 1-3 TB depending on pool usage
Protected: 1TB always available even if pool is 99% full
Maximum: 3TB even if pool is empty

Section 6: File Sharing Protocols

SMB/CIFS (Windows File Sharing)

Best For: Windows clients, macOS, general file sharing

Configuration Example: Media Share

Navigate to: Shares → Windows (SMB) Shares → Add

Basic Configuration:
Path: /mnt/tank/storage/media
Name: Media
Purpose: Media Library
Comment: Shared media files for Plex/Jellyfin

Advanced Options:
Enable: Yes
Read Only: No (allow writes)
Browsable to Network Clients: Yes
Guestok: No (require authentication)

Access Control:
Hosts Allow: 192.168.1.0/24 (your local network)
Hosts Deny: (leave empty for local network only)

Performance Tuning:
Async: Yes (better throughput)
Sendfile: Yes (large file optimization)

Shadow Copies:
Enable Shadow Copies: Yes (requires snapshots configured)

Accessing SMB Share:

Windows:

Open File Explorer
In address bar: \192.168.1.100Media
Enter credentials when prompted
Map network drive for persistent access

macOS:

Finder → Go → Connect to Server
smb://192.168.1.100/Media
Enter credentials
Add to login items for auto-mount

Linux:

# Install samba client
sudo apt install cifs-utils

# Create mount point
sudo mkdir /mnt/media

# Mount share
sudo mount -t cifs -o username=USER,password=PASS //192.168.1.100/Media /mnt/media

# Or add to /etc/fstab for auto-mount
//192.168.1.100/Media /mnt/media cifs credentials=/root/.smbcredentials,uid=1000,gid=1000 0 0

NFS (Network File System)

Best For: Linux/Unix clients, hypervisors (Proxmox, VMware), container hosts

Configuration Example: Container Storage

Navigate to: Shares → Unix (NFS) Shares → Add

Path: /mnt/tank/apps/docker
Description: Docker container storage

Networks:
Authorized Networks: 192.168.1.0/24
Authorized Hosts: (leave empty or specify specific hosts)

NFS Options:
Read Only: No
Mapall User: root
Mapall Group: root

Security:
NFSv4: Yes (recommended)
Security: SYS (or KRB5 if using Kerberos)

Advanced:
Quiet: No

Accessing NFS Share:

Linux:

# Install NFS client
sudo apt install nfs-common

# Create mount point
sudo mkdir -p /mnt/nas/docker

# Mount share
sudo mount -t nfs -o vers=4 192.168.1.100:/mnt/tank/apps/docker /mnt/nas/docker

# Add to /etc/fstab for auto-mount
192.168.1.100:/mnt/tank/apps/docker /mnt/nas/docker nfs4 defaults 0 0

Proxmox:

Datacenter → Storage → Add → NFS

ID: truenas-docker
Server: 192.168.1.100
Export: /mnt/tank/apps/docker
Content: VZDump backup file, Container, ISO image

Options:
NFS Version: 4

iSCSI (Block-Level Storage)

Best For: VMware ESXi, Hyper-V, database servers requiring block-level access

Configuration Example: VM Datastore

Step 1: Create ZVol (Block Device)

Storage → Datasets → Add Zvol

Name: esxi-datastore
Parent: tank/vms
Size: 1 TB
Block Size: 16K (VMware recommended)
Sparse: No (full allocation for production)

Step 2: Configure iSCSI Portal

Shares → iSCSI → Portals → Add

Discovery Authentication Method: None (or CHAP for security)
Portal IP Address: 0.0.0.0 (all interfaces) or specific IP
Port: 3260 (default)

Step 3: Create Initiator Group

Shares → iSCSI → Initiator Groups → Add

Initiators: ALL (or specify ESXi IQN)
Authorized Networks: 192.168.1.0/24
Description: ESXi Hosts

Step 4: Create Target

Shares → iSCSI → Targets → Add

Target Name: esxi-storage
Target Alias: ESXi Datastore
Portal Group: 1
Initiator Group: 1 (created in step 3)
Authentication Method: None (or CHAP)

Step 5: Create Extent

Shares → iSCSI → Extents → Add

Name: esxi-datastore-extent
Type: Device
Device: zvol/tank/vms/esxi-datastore
Logical Block Size: 512 (or 4096 for modern systems)

Step 6: Associate Target with Extent

Shares → iSCSI → Associated Targets → Add

Target: esxi-storage
LUN ID: 0
Extent: esxi-datastore-extent

Step 7: Start iSCSI Service

System → Services → iSCSI
Enable: Yes
Start Automatically: Yes

Accessing from VMware ESXi:

1. Log into vSphere/ESXi web interface
2. Navigate to Storage → Adapters
3. Software iSCSI → Configure → Dynamic Discovery
4. Add Target: 192.168.1.100:3260
5. Rescan Adapters
6. Navigate to Storage → Datastores → New Datastore
7. Create VMFS datastore on new iSCSI LUN

Protocol Comparison and Selection Guide

FeatureSMBNFSiSCSI
Protocol TypeFile-levelFile-levelBlock-level
Best ForWindows usersLinux serversVMs, databases
PerformanceGoodExcellentExcellent
Setup ComplexityLowMediumHigh
Windows SupportNativeThird-partyNative
macOS SupportNativeNativeLimited
Linux SupportNativeNativeNative
Multiple WritersYesYesNo (single host)
Recommended PriorityHighHighIf needed

Quick Selection Guide:

  • Home users: Start with SMB
  • Linux-heavy environment: Use NFS
  • Virtualization: Use iSCSI for datastores
  • Mixed environment: Use SMB + NFS multiprotocol
  • Media streaming: SMB or NFS work great
  • Container storage: NFS recommended

Section 7: Containerization and Applications

Docker on TrueNAS SCALE

TrueNAS SCALE v24.10+ includes native Docker support via Docker Compose. This is a game-changer for homelabbers.

Why Docker on TrueNAS?

  • Isolate applications and dependencies
  • Easy installation and updates
  • No system library conflicts
  • Enhanced security through containerization
  • Access to thousands of pre-built images

Installing Apps from TrueNAS Catalog

Popular Homelab Apps:

  1. Plex Media Server
Navigate to: Apps → Discover → Plex

Configuration:
Storage:
  - Config: /mnt/tank/apps/plex/config
  - Media: /mnt/tank/storage/media
Network:
  - Host Network: Yes (recommended for auto-discovery)
  - Port: 32400
Resources:
  - CPU: 4 cores
  - Memory: 4 GB
  1. Jellyfin (Open-Source Media Server)
Apps → Discover → Jellyfin

Configuration:
Storage:
  - Config: /mnt/tank/apps/jellyfin/config
  - Media: /mnt/tank/storage/media
Network:
  - Port 8096: HTTP
  - Port 8920: HTTPS
Resources:
  - CPU: 2-4 cores
  - Memory: 2-4 GB
  1. Home Assistant
Apps → Discover → Home Assistant

Configuration:
Storage:
  - Config: /mnt/tank/apps/homeassistant/config
Network:
  - Host Network: Yes (for device discovery)
  - Port: 8123
Devices:
  - USB Zigbee/Z-Wave stick: Pass through if needed
  1. Nextcloud
Apps → Discover → Nextcloud

Configuration:
Storage:
  - Data: /mnt/tank/apps/nextcloud/data
  - Config: /mnt/tank/apps/nextcloud/config
  - Database: PostgreSQL (included)
Network:
  - Port 8080: HTTP
  - Port 8443: HTTPS
Resources:
  - CPU: 2-4 cores
  - Memory: 2-4 GB

Custom Docker Compose Deployments

Example: Nginx Reverse Proxy

# /mnt/tank/apps/nginx/docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    restart: unless-stopped

    ports:
      - "80:80"
      - "443:443"

    volumes:
      - /mnt/tank/apps/nginx/html:/usr/share/nginx/html:ro
      - /mnt/tank/apps/nginx/conf:/etc/nginx/conf.d:ro
      - /mnt/tank/apps/nginx/certs:/etc/nginx/certs:ro
      - /mnt/tank/apps/nginx/logs:/var/log/nginx

    networks:
      - proxy_network

    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

networks:
  proxy_network:
    driver: bridge

Deploying Custom Docker Compose:

Navigate to: Apps → Discover → Launch Docker Image

1. Select "Custom App"
2. Name: nginx-proxy
3. Docker Compose YAML: Paste above configuration
4. Deploy
5. Monitor logs: Apps → Installed → nginx-proxy → Logs

Docker Volume Management Best Practices

Storage Strategy:

Dataset Structure for Apps:
/mnt/tank/apps/
├── plex/
│   ├── config/          # Application configuration
│   ├── library/         # Plex database
│   └── transcode/       # Temporary transcoding
├── jellyfin/
│   ├── config/
│   └── cache/
├── nextcloud/
│   ├── data/            # User files
│   ├── config/
│   └── database/
├── homeassistant/
│   └── config/
└── docker-registry/
    └── images/

Benefits of ZFS-Backed Storage:

  • Data survives container deletion
  • Easy backups via ZFS snapshots
  • Can be shared between containers
  • Supports ZFS features (compression, encryption, replication)
  • Better performance than container overlay storage

Resource Limits Example

# Comprehensive resource management

services:
  myapp:
    image: myapp:latest
    container_name: myapp

    deploy:
      resources:
        limits:
          cpus: '4'              # Max 4 CPU cores
          memory: 8G             # Max 8GB RAM
          pids: 100              # Max 100 processes
        reservations:
          cpus: '2'              # Reserved minimum
          memory: 4G             # Reserved minimum

    # Storage I/O limits (if needed)
    blkio_config:
      weight: 500
      weight_device:
        - path: /dev/sda
          weight: 300

    # CPU scheduling
    cpu_shares: 1024              # Relative CPU priority
    cpuset: "0-3"                 # Bind to specific cores

    # Memory management
    mem_swappiness: 0             # Minimize swapping
    oom_kill_disable: false       # Allow OOM killer
    oom_score_adj: 0              # OOM killer priority

TrueNAS Recommendations:

  • Reserve 20-30% system resources for TrueNAS itself
  • Allocate 50-70% to containers/applications
  • Leave 10% buffer for overhead
  • Monitor resource usage: System → Monitor

Container Health Monitoring

Built-in Health Checks:

services:
  webapp:
    image: mywebapp:latest

    healthcheck:
      # Command to test health
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]

      # How often to check
      interval: 30s

      # Max time for check to complete
      timeout: 10s

      # How many failures before unhealthy
      retries: 3

      # Initial delay before first check
      start_period: 60s

Monitoring in TrueNAS:

Apps → Installed Applications
View status: Running, Starting, Stopped, Unhealthy
Click container → View Logs
Click container → Shell (for debugging)

Section 8: Backup, Snapshot, and Replication Strategies

The 3-2-1 Backup Rule for Homelabs

Rule: 3 copies of data, on 2 different media types, with 1 copy offsite

Applied to TrueNAS:

  1. Primary copy: Live data on TrueNAS pool
  2. Second copy: Local snapshots on same pool
  3. Third copy: Replicated to remote NAS or cloud

Understanding Snapshots

What Snapshots ARE:

  • Read-only, point-in-time copies of datasets
  • Consume minimal space (copy-on-write)
  • Instant creation (even for 10TB datasets)
  • Can be rolled back (restore dataset to snapshot state)
  • Can be browsed directly

What Snapshots are NOT:

  • A complete backup solution
  • Protection against pool failure
  • Protection against ransomware (if snapshot is accessible)
  • Suitable for long-term archival alone

Creating Automatic Snapshot Tasks

Multi-Level Retention Strategy (Recommended):

Strategy:
- Hourly snapshots: Keep 24 hours
- Daily snapshots: Keep 7 days
- Weekly snapshots: Keep 4 weeks
- Monthly snapshots: Keep 12 months

Result: Point-in-time recovery from 1 hour ago to 1 year ago

Implementation:

Task 1: Hourly Snapshots

Navigate to: Data Protection → Periodic Snapshot Tasks → Add

Dataset: tank/storage
Recursive: Yes (include child datasets)
Schedule: Hourly at :00
Naming Schema: hourly-%Y%m%d-%H%M%S
Lifetime: 24 hours

Result: 24 snapshots covering last day, hourly granularity

Task 2: Daily Snapshots

Data Protection → Periodic Snapshot Tasks → Add

Dataset: tank/storage
Recursive: Yes
Schedule: Daily at 01:00
Naming Schema: daily-%Y%m%d-%H%M%S
Lifetime: 7 days

Result: 7 snapshots covering last week, daily granularity

Task 3: Weekly Snapshots

Data Protection → Periodic Snapshot Tasks → Add

Dataset: tank/storage
Recursive: Yes
Schedule: Weekly on Sunday at 02:00
Naming Schema: weekly-%Y%m%d-%H%M%S
Lifetime: 28 days (4 weeks)

Result: 4 snapshots covering last month, weekly granularity

Task 4: Monthly Snapshots

Data Protection → Periodic Snapshot Tasks → Add

Dataset: tank/storage
Recursive: Yes
Schedule: Monthly on 1st at 03:00
Naming Schema: monthly-%Y%m%d-%H%M%S
Lifetime: 365 days (12 months)

Result: 12 snapshots covering last year, monthly granularity

Total Snapshot Count: 24 + 7 + 4 + 12 = 47 snapshots per dataset

Browsing and Restoring from Snapshots

Method 1: Web UI Browse

Storage → Snapshots
Select snapshot → Browse
Navigate filesystem
Right-click file → Restore or Copy

Method 2: Direct Access (SMB Shadow Copies)

Windows File Explorer:
1. Navigate to shared folder
2. Right-click file or folder
3. Properties → Previous Versions
4. Select snapshot by date/time
5. Restore or Copy

Method 3: Command Line (SSH)

# List snapshots
zfs list -t snapshot

# Browse snapshot
cd /mnt/tank/storage/.zfs/snapshot/daily-20251216-010000/

# Copy file from snapshot
cp /mnt/tank/storage/.zfs/snapshot/daily-20251216-010000/important.txt /mnt/tank/storage/

Setting Up Remote Replication

Scenario: Replicate to remote TrueNAS at friend’s house for offsite backup

Prerequisites:

  • Remote TrueNAS accessible over network (VPN recommended)
  • SSH connectivity established
  • Sufficient storage on remote system

Step 1: Configure SSH Key Pair

On Source NAS:

System → SSH Keypairs → Add

Name: remote-backup-key
Type: SSH Key Pair
Generate Keypair: Yes

Save the private key securely!
Copy the public key

On Destination NAS:

System → SSH Connections → Add

Name: friend-nas
Host: friend-nas.tailscale.net (or IP)
Port: 22
Username: backup-user
Private Key: Paste private key from source

Test Connection: Click to verify

Step 2: Create Replication Task

Data Protection → Replication Tasks → Add

Source Location: Local
Source Dataset: tank/storage
Recursive: Yes (include child datasets)

Destination Location: Remote
SSH Connection: friend-nas
Destination Dataset: backups/my-nas

Transport: SSH
SSH Transfer Security: (default)

Task Schedule:
Schedule: Daily
Time: 03:00 AM

Snapshot Retention:
Source: Keep 7 snapshots
Destination: Keep 30 snapshots

Replication Options:
Compression: lz4-fastest (reduces bandwidth)
Large Block: Yes
Embed Data: No (reduces bandwidth)
Compressed Write: Yes

Enable Task: Yes

Save and Run Now (to test)

Monitoring Replication:

Data Protection → Replication Tasks
View Status: SUCCESS, RUNNING, FAILED
View Log: Click task → View Log
View Transfer Stats: Speed, data transferred

Practical Multi-Tier Backup Example

Complete Backup Architecture:

Tier 1: Local Snapshots (Fast Recovery)
Dataset: tank/storage
Schedule: Hourly, Daily, Weekly, Monthly
Retention: 24h + 7d + 4w + 12m
Recovery Time: Minutes
Protects Against: Accidental deletion, file corruption

Tier 2: Local Replication (Hardware Redundancy)
Source: tank/storage
Destination: backup-pool/replicas (secondary pool, same NAS)
Schedule: Hourly
Retention: 7 days
Recovery Time: Minutes
Protects Against: Pool failure, disk failures

Tier 3: Remote Replication (Disaster Recovery)
Source: tank/storage
Destination: friend-nas:/backups/my-nas
Schedule: Daily at 3 AM
Retention: 30 days
Recovery Time: Hours
Protects Against: Complete NAS failure, fire, theft

Tier 4: Cloud Backup (Critical Data Only)
Source: tank/storage/documents + photos
Destination: Backblaze B2 / Wasabi
Tool: restic or rclone
Schedule: Daily at 4 AM
Encryption: Yes (AES-256)
Retention: 90 days
Recovery Time: Hours to days
Protects Against: Complete site loss, natural disaster

Recovery Scenarios

Scenario 1: Accidental File Deletion (Common)

Problem: User deletes important file

Solution:

Time to Recovery: 5 minutes
Data Loss: None (if recent snapshot exists)

Steps:
1. Storage → Snapshots
2. Find snapshot before deletion
3. Browse snapshot filesystem
4. Locate file
5. Copy file back to live dataset

Alternative (Windows):
1. Right-click folder → Properties
2. Previous Versions tab
3. Select snapshot
4. Restore file

Scenario 2: Ransomware Attack (Critical)

Problem: Ransomware encrypts data

Solution:

Time to Recovery: 2-4 hours
Data Loss: Changes since last clean snapshot

Steps:
1. Identify infection time
2. Find snapshot before infection
3. Create new dataset: tank/storage-clean
4. Replicate clean snapshot to new dataset:
   zfs send tank/storage@clean | zfs receive tank/storage-clean
5. Verify data integrity
6. Reconfigure shares to point to clean dataset
7. Delete infected dataset after verification
8. Investigate infection vector
9. Restore from clean backup

Prevention:

  • Air-gapped backups (offline USB drives)
  • Immutable snapshots (snapshot retention locked)
  • Limited SMB permissions
  • Regular security updates

Scenario 3: Complete NAS Failure (Worst Case)

Problem: Motherboard failure, multiple disk failures, fire

Solution:

Time to Recovery: 1-3 days
Data Loss: Changes since last remote replication (typically <24h)

Steps:
1. Obtain replacement hardware
2. Install TrueNAS SCALE
3. Configure network (same IP if possible)
4. Create new pool with available drives
5. Configure SSH connection to remote backup
6. Create reverse replication task:
   Source: friend-nas:/backups/my-nas
   Destination: tank/storage
7. Run replication (may take hours depending on data size)
8. Verify data integrity
9. Reconfigure shares and applications
10. Resume normal operations

Required:
- Remote backup system must be accessible
- SSH credentials must be available
- Sufficient storage on replacement system

Cloud Backup Integration (Optional)

Using rclone for Cloud Backup:

# Install rclone (SSH into TrueNAS)
sudo apt install rclone

# Configure rclone for Backblaze B2
rclone config
# Follow prompts for Backblaze B2 or Wasabi S3

# Create backup script
cat > /root/cloud-backup.sh << 'EOF'
#!/bin/bash

# Backup critical data to cloud
SOURCE="/mnt/tank/storage/documents"
DEST="b2:my-backup-bucket/documents"

# Sync with encryption
rclone sync "$SOURCE" "$DEST"   --crypt-password="YOUR_ENCRYPTION_PASSWORD"   --crypt-password2="YOUR_SALT"   --transfers=4   --checkers=8   --log-file=/var/log/cloud-backup.log   --log-level INFO   --exclude ".DS_Store"   --exclude "Thumbs.db"

# Backup photos
rclone sync /mnt/tank/storage/photos "$DEST/../photos"   --transfers=4   --log-file=/var/log/cloud-backup.log

echo "Cloud backup completed: $(date)"
EOF

chmod +x /root/cloud-backup.sh

# Schedule via cron
crontab -e
# Add: 0 4 * * * /root/cloud-backup.sh

Cost Estimate (Backblaze B2):

  • 1 TB storage: $6/month
  • Download fees: $0.01/GB (free egress via Cloudflare)
  • Total: ~$6-10/month for 1TB backup

Section 9: AI and Automation Opportunities

Why AI on TrueNAS?

TrueNAS SCALE provides an excellent platform for AI workloads due to:

  • High-throughput storage for model and dataset hosting
  • Native Docker support for ML frameworks
  • ZFS snapshots for experiment versioning
  • Direct S3 API compatibility (via MinIO) for ML frameworks

Local LLM Inference with Ollama

What is Ollama? Run large language models locally without internet dependency or cloud API costs.

Installation:

Navigate to: Apps → Discover → Ollama

Configuration:
Storage:
  - Models: /mnt/tank/ai/ollama/models (persistent model storage)
  - Data: /mnt/tank/ai/ollama/data
Network:
  - Port 11434: API endpoint
  - Host Network: Optional
Resources:
  - CPU: 4-8 cores
  - Memory: 16-32 GB (depending on model size)
  - GPU: Optional (RTX 3060, 4070, etc. for faster inference)

Deploy

Using Ollama:

# SSH into TrueNAS or use Ollama container shell

# Pull models (various sizes available)
ollama pull mistral:7b          # 7B parameter model (~4GB)
ollama pull llama2:13b          # 13B parameter model (~7GB)
ollama pull codellama:34b       # 34B parameter model (~19GB)

# Run model
ollama run mistral:7b

# Example prompts
>>> Explain ZFS in simple terms
>>> Write a Python script to monitor TrueNAS pool health
>>> Help me design a backup strategy for my homelab

# API usage (from other applications)
curl http://localhost:11434/api/generate -d '{
  "model": "mistral:7b",
  "prompt": "Explain RAID-Z2"
}'

Hardware Requirements by Model Size:

7B models (Mistral, Llama2-7B):
- RAM: 16 GB minimum
- VRAM (GPU): 6-8 GB
- Inference Speed: 10-20 tokens/sec (CPU), 40-80 tokens/sec (GPU)
- Use Case: General tasks, coding assistance

13B models (Llama2-13B):
- RAM: 32 GB minimum
- VRAM (GPU): 12-16 GB
- Inference Speed: 5-10 tokens/sec (CPU), 20-40 tokens/sec (GPU)
- Use Case: More complex reasoning, better quality

34B models (CodeLlama-34B):
- RAM: 64 GB minimum
- VRAM (GPU): 24 GB (RTX 4090, A5000)
- Inference Speed: 2-5 tokens/sec (CPU), 10-20 tokens/sec (GPU)
- Use Case: Advanced coding, complex tasks

AI-Powered Document Management with Paperless-AI

What is Paperless-AI? Automated document management with OCR and AI classification.

Installation:

Apps → Discover → Paperless-AI

Configuration:
Storage:
  - Data: /mnt/tank/apps/paperless/data
  - Media: /mnt/tank/apps/paperless/media
  - Consume: /mnt/tank/apps/paperless/consume
Database:
  - PostgreSQL: Use built-in or external
Network:
  - Port 8000: Web UI
Resources:
  - CPU: 2-4 cores
  - Memory: 2-4 GB

Deploy

Features:

  • Automatic OCR of scanned documents
  • AI-powered document classification
  • Tag suggestions based on content
  • Full-text search across all documents
  • Email import (scan to email → auto-import)
  • Mobile app support

Workflow Example:

1. Scan document → Email to [email protected]
2. Paperless-AI receives email attachment
3. OCR extracts text
4. AI classifies document type (invoice, receipt, contract, etc.)
5. AI suggests tags (tax, utilities, medical, etc.)
6. Document stored and searchable
7. Original file preserved on ZFS with snapshots

Frigate: AI-Powered Video Security

What is Frigate? Real-time object detection for security cameras using AI.

Installation:

Apps → Discover → Frigate

Configuration:
Storage:
  - Config: /mnt/tank/apps/frigate/config
  - Media: /mnt/tank/apps/frigate/media (video recordings)
Network:
  - Port 5000: Web UI
  - Port 1935: RTMP
  - Port 8554: RTSP
Resources:
  - CPU: 4-8 cores
  - Memory: 4-8 GB
  - GPU: Highly recommended (Coral TPU or NVIDIA GPU)

GPU Passthrough (if available):
  - Pass through NVIDIA GPU for TensorRT acceleration
  - Or use Google Coral USB Accelerator

Deploy

Configuration Example (/mnt/tank/apps/frigate/config/config.yml):

mqtt:
  host: 192.168.1.100  # Home Assistant or MQTT broker

detectors:
  coral:
    type: edgetpu
    device: usb

cameras:
  front_door:
    ffmpeg:
      inputs:
        - path: rtsp://192.168.1.201:554/stream
          roles:
            - detect
            - record
    detect:
      width: 1280
      height: 720
      fps: 5
    objects:
      track:
        - person
        - car
        - dog
      filters:
        person:
          min_area: 5000
          max_area: 100000
          threshold: 0.75

  backyard:
    ffmpeg:
      inputs:
        - path: rtsp://192.168.1.202:554/stream
          roles:
            - detect
            - record
    detect:
      width: 1920
      height: 1080
      fps: 5
    objects:
      track:
        - person
        - cat
        - dog

record:
  enabled: True
  retain:
    days: 7
    mode: motion
  events:
    retain:
      default: 30
      mode: active_objects

snapshots:
  enabled: True
  retain:
    default: 30

Features:

  • Real-time person/vehicle/pet detection
  • Event-based recording (motion + object detection)
  • Integration with Home Assistant
  • Live view with object highlighting
  • Historical event search
  • Notification triggers

Performance: With Google Coral TPU, processes ~100 FPS across multiple cameras.

Home Assistant Integration

Connecting TrueNAS to Home Assistant:

1. Monitor TrueNAS Health:

# configuration.yaml

sensor:
  - platform: rest
    name: TrueNAS Pool Capacity
    resource: http://192.168.1.100/api/v2.0/pool
    headers:
      Authorization: Bearer YOUR_API_KEY
    value_template: '[[ value_json[0].topology.data[0].stats.free ]]'
    unit_of_measurement: "bytes"

  - platform: rest
    name: TrueNAS Pool Health
    resource: http://192.168.1.100/api/v2.0/pool
    headers:
      Authorization: Bearer YOUR_API_KEY
    value_template: '[[ value_json[0].status ]]'

automation:
  - alias: "Alert: TrueNAS Pool Capacity Warning"
    trigger:
      platform: numeric_state
      entity_id: sensor.truenas_pool_capacity
      below: 1000000000000  # 1TB free
    action:
      - service: notify.mobile_app
        data:
          title: "TrueNAS Storage Alert"
          message: "Pool has less than 1TB free space"
          data:
            priority: high

  - alias: "Alert: TrueNAS Pool Degraded"
    trigger:
      platform: state
      entity_id: sensor.truenas_pool_health
      to: 'DEGRADED'
    action:
      - service: notify.mobile_app
        data:
          title: "TrueNAS CRITICAL"
          message: "Pool is DEGRADED - check immediately!"
          data:
            priority: critical
            push:
              sound: alarm.wav

2. Automate Backups Based on Events:

automation:
  - alias: "Trigger Backup Before System Updates"
    trigger:
      platform: state
      entity_id: update.truenas_update_available
      to: 'on'
    action:
      - service: shell_command.truenas_snapshot
        data:
          snapshot_name: "pre-update-[[ now().strftime('%Y%m%d-%H%M%S') ]]"
      - service: notify.mobile_app
        data:
          message: "Pre-update snapshot created"

shell_command:
  truenas_snapshot: >
    ssh [email protected]
    "zfs snapshot -r tank/storage@[[ snapshot_name ]]"

TrueNAS Core MCP Server (Model Context Protocol)

What is MCP? Allows AI models (Claude, GPT) to interact with TrueNAS via natural language.

Example Interactions:

User: "Create a dataset for my media library with SMB sharing"
AI: [Creates dataset tank/storage/media, configures SMB share, sets permissions]

User: "Back up my documents with daily snapshots"
AI: [Creates periodic snapshot task with 7-day retention]

User: "Who has access to the finance folder?"
AI: [Queries ACL permissions, reports users and groups]

User: "Show me pool health and recent errors"
AI: [Retrieves pool status, scrub results, recent error logs]

Benefits:

  • Natural language management
  • Automated routine tasks
  • Quick information retrieval
  • Reduced learning curve for beginners

Machine Learning Workload Storage

MLOps Pipeline on TrueNAS:

Storage Structure:
/mnt/tank/ml/
├── models/              # Trained model storage
│   ├── production/      # Production models
│   ├── staging/         # Testing models
│   └── archive/         # Historical models
├── datasets/            # Training datasets
│   ├── raw/             # Unprocessed data
│   ├── processed/       # Cleaned data
│   └── augmented/       # Augmented datasets
├── experiments/         # Experiment tracking
│   ├── exp-001/
│   ├── exp-002/
│   └── exp-003/
└── output/              # Training results
    ├── logs/
    ├── checkpoints/
    └── metrics/

Sharing:
- MinIO S3: For ML framework compatibility
- NFS: For direct filesystem access
- iSCSI: For high-performance database storage

Snapshots:
- Experiment snapshots before training runs
- Model versioning via snapshots
- Dataset snapshots for reproducibility

Example: PyTorch Training with TrueNAS Storage:

# train.py - Training script accessing TrueNAS

import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import os

# NFS mount: TrueNAS /mnt/tank/ml → /mnt/nas/ml
DATASET_PATH = "/mnt/nas/ml/datasets/processed/imagenet"
MODEL_OUTPUT = "/mnt/nas/ml/experiments/exp-042"
CHECKPOINT_PATH = f"{MODEL_OUTPUT}/checkpoints"

# Create experiment directory
os.makedirs(CHECKPOINT_PATH, exist_ok=True)

# Load dataset from TrueNAS
dataset = torch.utils.data.ImageFolder(DATASET_PATH)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)

# Training loop
model = MyModel()
optimizer = torch.optim.Adam(model.parameters())

for epoch in range(100):
    for batch in dataloader:
        # Training code
        loss = train_step(model, batch, optimizer)

    # Save checkpoint to TrueNAS every epoch
    if epoch % 10 == 0:
        torch.save({
            'epoch': epoch,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'loss': loss,
        }, f"{CHECKPOINT_PATH}/checkpoint_epoch_{epoch}.pt")

        # ZFS snapshot for versioning (via SSH or API)
        os.system(f"ssh admin@truenas 'zfs snapshot tank/ml/experiments/exp-042@epoch-{epoch}'")

Automated Storage Optimization

AI-Powered Storage Recommendations:

# storage_optimizer.py - Analyzes usage patterns and suggests optimizations

import requests
import json
from datetime import datetime, timedelta

TRUENAS_API = "http://192.168.1.100/api/v2.0"
API_KEY = "your_api_key_here"

headers = {"Authorization": f"Bearer {API_KEY}"}

def analyze_dataset_usage():
    """Analyze dataset access patterns and suggest compression changes"""

    # Get all datasets
    response = requests.get(f"{TRUENAS_API}/pool/dataset", headers=headers)
    datasets = response.json()

    recommendations = []

    for dataset in datasets:
        name = dataset['name']
        compression = dataset['compression']['value']
        used = dataset['used']['parsed']
        available = dataset['available']['parsed']

        # Get access statistics (simplified)
        # In reality, parse ZFS access time stats
        last_access = get_last_access_time(name)

        if last_access > timedelta(days=90):
            # Cold data - recommend higher compression
            if compression == 'lz4':
                recommendations.append({
                    'dataset': name,
                    'current_compression': compression,
                    'recommended_compression': 'gzip-6',
                    'reason': 'Cold data (&gt;90 days), benefit from higher compression',
                    'estimated_savings': '30-40%'
                })

        elif used / (used + available) &gt; 0.85:
            # Low space - recommend compression if not enabled
            if compression == 'off':
                recommendations.append({
                    'dataset': name,
                    'current_compression': compression,
                    'recommended_compression': 'lz4',
                    'reason': 'Low space warning, enable compression',
                    'estimated_savings': '20-30%'
                })

    return recommendations

def apply_recommendations(recommendations):
    """Apply recommended compression changes"""
    for rec in recommendations:
        print(f"Applying to {rec['dataset']}: {rec['recommended_compression']}")

        # Apply via API
        requests.put(
            f"{TRUENAS_API}/pool/dataset/id/{rec['dataset']}",
            headers=headers,
            json={'compression': rec['recommended_compression']}
        )

# Run analysis
recs = analyze_dataset_usage()
print(json.dumps(recs, indent=2))

# Optional: Auto-apply (use caution!)
# apply_recommendations(recs)

Predictive Disk Failure Detection

ML-Based SMART Analysis:

# disk_health_ml.py - Predict disk failures using SMART data

import requests
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
import joblib

TRUENAS_API = "http://192.168.1.100/api/v2.0"
API_KEY = "your_api_key"
headers = {"Authorization": f"Bearer {API_KEY}"}

def get_smart_data():
    """Retrieve SMART data for all disks"""
    response = requests.get(f"{TRUENAS_API}/disk", headers=headers)
    disks = response.json()

    smart_data = []
    for disk in disks:
        name = disk['name']

        # Get SMART attributes
        smart_response = requests.post(
            f"{TRUENAS_API}/disk/smartctl",
            headers=headers,
            json={'devname': name, 'type': 'SMART'}
        )

        if smart_response.status_code == 200:
            smart = smart_response.json()
            smart_data.append({
                'disk': name,
                'temperature': smart.get('temperature', {}).get('current'),
                'power_on_hours': smart.get('power_on_time', {}).get('hours'),
                'reallocated_sectors': smart.get('ata_smart_attributes', {}).get('table', [{}])[5].get('raw', {}).get('value', 0),
                'pending_sectors': smart.get('ata_smart_attributes', {}).get('table', [{}])[197].get('raw', {}).get('value', 0),
                'uncorrectable_sectors': smart.get('ata_smart_attributes', {}).get('table', [{}])[198].get('raw', {}).get('value', 0),
            })

    return pd.DataFrame(smart_data)

def predict_failures(smart_df, model_path='disk_failure_model.pkl'):
    """Predict which disks are likely to fail"""

    # Load pre-trained model (train on historical failure data)
    model = joblib.load(model_path)

    # Features for prediction
    features = ['temperature', 'power_on_hours', 'reallocated_sectors',
                'pending_sectors', 'uncorrectable_sectors']

    # Predict failure probability
    smart_df['failure_probability'] = model.predict_proba(smart_df[features])[:, 1]

    # Flag high-risk disks
    smart_df['risk_level'] = smart_df['failure_probability'].apply(
        lambda x: 'HIGH' if x &gt; 0.7 else 'MEDIUM' if x &gt; 0.4 else 'LOW'
    )

    return smart_df

def send_alerts(predictions):
    """Send alerts for high-risk disks"""
    high_risk = predictions[predictions['risk_level'] == 'HIGH']

    if not high_risk.empty:
        for _, disk in high_risk.iterrows():
            message = f"""
            DISK FAILURE WARNING

            Disk: {disk['disk']}
            Failure Probability: {disk['failure_probability']:.2%}

            SMART Indicators:
            - Temperature: {disk['temperature']}°C
            - Power-On Hours: {disk['power_on_hours']:,}
            - Reallocated Sectors: {disk['reallocated_sectors']}
            - Pending Sectors: {disk['pending_sectors']}
            - Uncorrectable Sectors: {disk['uncorrectable_sectors']}

            RECOMMENDATION: Replace this disk soon.
            """

            # Send via email, Slack, etc.
            send_notification(message)
            print(message)

# Run prediction pipeline
smart_data = get_smart_data()
predictions = predict_failures(smart_data)
send_alerts(predictions)

# Save report
predictions.to_csv('/mnt/tank/reports/disk_health.csv', index=False)

Benefits:

  • Proactive disk replacement before failure
  • Reduced downtime
  • Data loss prevention
  • Cost savings (planned replacement vs emergency)

Section 10: Troubleshooting and Maintenance

Common Issues and Solutions

Issue 1: Pool Shows Degraded Status

Symptoms:

  • Web UI shows red “DEGRADED” pool status
  • One or more disks showing as unavailable
  • Email alerts about disk failure

Diagnosis:

Storage → Pools → [pool name]
- Note which disk/vdev is degraded
- Check error count
- Review system logs

Solution:

1. Identify failed device:
   Storage → Disks → Review disk list
   Look for "UNAVAIL" or "FAULTED" status

2. Check physical connection:
   - Shutdown system safely
   - Reseat disk in bay
   - Check SATA/SAS cables
   - Power on system

3. If disk is truly failed:
   a. Shutdown system
   b. Remove failed disk
   c. Insert replacement disk (same or larger size)
   d. Power on system

4. TrueNAS auto-begins resilvering:
   Monitor: Storage → Pools → Status
   Estimated time: 2-8 hours per TB

5. After resilver completes:
   Pool returns to "ONLINE" status
   Run scrub to verify: Storage → Pools → Scrub Pool

Prevention:

  • Monitor SMART data weekly: Storage → Disks → SMART Test
  • Replace disks showing warnings proactively
  • Implement hot spares: Automatic replacement
  • Temperature monitoring: Keep disks below 45°C

Issue 2: Low Pool Performance

Symptoms:

  • File transfers slower than expected
  • Web interface sluggish
  • High CPU usage

Diagnosis:

System → Monitor
- Check CPU usage
- Check memory usage (ARC stats)
- Check disk I/O

System → Tasks
- Check if scrub is running
- Check if replication is running

Common Causes and Solutions:

1. Insufficient RAM / Small ARC:

Symptom: ARC hit ratio &lt; 70%
Solution: Add more RAM
Check: System → Monitor → Memory → ARC Stats

Temporary workaround:
- Reduce compression on hot datasets
- Disable deduplication if enabled
- Close unnecessary applications

2. Pool Scrub Running:

Symptom: High disk I/O, slow response
Solution: Expected behavior, wait for completion
Check: Storage → Pools → [pool] → Status
Duration: Several hours depending on pool size

Optimization: Schedule scrubs during off-hours

3. Too Many Snapshots:

Symptom: Slow dataset operations
Solution: Review and delete old snapshots
Check: Storage → Snapshots → Count per dataset

Cleanup:
Storage → Snapshots
Filter by dataset
Delete old snapshots (keep important ones)
Adjust retention policies

4. Deduplication Enabled Without Sufficient RAM:

Symptom: Very high CPU usage, slow writes
Solution: Disable deduplication if RAM &lt; 5GB per TB deduplicated
Check: Storage → Datasets → [dataset] → Deduplication

To disable (cannot undo!):
zfs set dedup=off tank/storage
Note: Already deduplicated data remains deduplicated

Regular Maintenance Tasks

Daily (Automated):

- Automatic snapshots execute
- Replication tasks run
- SMART monitoring active
- Alert system monitoring

Weekly (Manual - 10 minutes):

1. Review pool health:
   Storage → Pools → Check all pools "ONLINE"

2. Check available space:
   Storage → Pools → Verify &lt;80% capacity

3. Review recent alerts:
   System → Events → Filter last 7 days

4. Test file restoration:
   Storage → Snapshots → Restore test file

Monthly (Manual - 30 minutes):

1. Run pool scrub:
   Storage → Pools → [pool] → Scrub Pool
   Duration: 2-12 hours
   Purpose: Verify data integrity, repair errors

2. Review SMART data:
   Storage → Disks → SMART Test (all disks)
   Look for warnings or increasing error counts

3. Test backup restoration:
   Restore file from remote replication
   Verify integrity

4. Review disk temperatures:
   Storage → Disks → Check all disks &lt;45°C
   Clean dust if temperatures elevated

5. Update TrueNAS (if available):
   System → Update
   Review release notes first
   Schedule during maintenance window

Quarterly (Manual - 2 hours):

1. Test disaster recovery:
   Simulate NAS failure
   Practice restoration from remote backup
   Document any issues

2. Review and update documentation:
   Update pool configuration docs
   Update network configuration
   Update recovery procedures

3. Security audit:
   Review user accounts
   Review SSH keys
   Review alert contacts
   Test 2FA if enabled

4. Capacity planning:
   Review growth trends
   Plan for expansions
   Budget for additional drives

5. Check for firmware updates:
   HBA firmware
   Drive firmware
   Motherboard BIOS

Pool Scrubbing Explained

What is Scrubbing?

  • Reads every block in the pool
  • Verifies checksums
  • Repairs errors if redundancy available
  • Prevents silent data corruption

When to Scrub:

  • Monthly for active systems
  • Quarterly for cold storage
  • After hardware changes
  • Before major upgrades

Scrub Process:

Storage → Pools → [pool] → Scrub Pool

Status messages:
- "In Progress" - Scrub running
- "Completed" - No errors found
- "Completed with Errors" - Errors detected and repaired

Monitoring:
Check progress: Storage → Pools → Status
Estimated time: 1-2 hours per TB
Performance impact: Minimal on RAID-Z, moderate on mirrors

Logs and Monitoring

Accessing Logs:

System → Events
- Filter by severity: INFO, WARNING, ALERT, CRITICAL
- Filter by date range
- Search specific keywords
- Export logs for analysis

Task-Specific Logs:
Data Protection → [Task Type] → [Task] → View Log
- Replication logs
- Snapshot logs
- Scrub logs

System Logs (SSH):
ssh [email protected]
tail -f /var/log/messages        # System messages
tail -f /var/log/syslog           # Syslog
tail -f /var/log/daemon.log       # Service logs
zpool status -v                   # Pool status
zpool iostat -v 5                 # I/O stats every 5 seconds

Performance Monitoring:

System → Monitor

Real-time Graphs:
- CPU usage (%)
- Memory usage (%)
- Disk I/O (MB/s)
- Network I/O (Mbps)
- ARC stats (hit ratio, size)

Historical Data:
- View trends over time
- Identify patterns
- Plan capacity

Export Data:
- Download CSV for analysis
- Import to Grafana for visualization

Conclusion and Next Steps

Key Takeaways

You’ve Learned:

  1. TrueNAS SCALE is the recommended choice for modern homelabs
  2. ZFS provides enterprise-grade data protection
  3. RAID-Z2 offers best balance for most deployments
  4. Multi-tier backup strategy is essential (snapshots + replication + offsite)
  5. Docker integration enables powerful application hosting
  6. AI workloads thrive on TrueNAS storage
  7. Regular monitoring and maintenance prevent most issues

Your TrueNAS System Now Provides:

  • Reliable, redundant storage
  • Protection against hardware failure
  • Fast recovery from accidental deletion
  • Disaster recovery capability
  • Application hosting platform
  • AI/ML workload support
  • Professional-grade data management

Your Next Steps

Week 1: Basic Setup

✓ Install TrueNAS SCALE
✓ Create pool with RAID-Z2
✓ Create essential datasets
✓ Configure SMB/NFS shares
✓ Set up automatic snapshots
✓ Configure alerts

Week 2: Enhanced Protection

✓ Set up remote replication
✓ Test file restoration
✓ Deploy first Docker application
✓ Configure UPS integration
✓ Document your configuration

Month 1: Advanced Features

✓ Deploy media server (Plex/Jellyfin)
✓ Set up Home Assistant
✓ Configure cloud backup (critical data)
✓ Test disaster recovery procedure
✓ Optimize performance

Ongoing: Maintenance and Growth

✓ Weekly health checks
✓ Monthly scrubs
✓ Quarterly disaster recovery tests
✓ Annual capacity planning
✓ Continuous learning and improvement

Continuing Your Learning

Advanced Topics to Explore:

  • ZFS expansion (SCALE only)
  • GPU passthrough for AI workloads
  • Multi-site replication strategies
  • Custom automation scripts
  • High availability configurations

Recommended Resources:

YouTube Channels:

  • TechnoTim: TrueNAS and homelab tutorials
  • Lawrence Systems: Storage and networking in-depth
  • WunderTech: Practical NAS setup guides
  • Craft Computing: Homelab optimization and builds

Community Engagement

Share Your Journey:

  • Document your build on r/homelab
  • Share lessons learned on TrueNAS forums
  • Help others getting started
  • Contribute to community guides

Stay Updated:

  • Follow TrueNAS on Twitter/Reddit
  • Subscribe to release notes
  • Join Discord communities
  • Attend virtual homelab meetups

Final Thoughts

TrueNAS represents a professional-grade storage solution accessible to homelabbers. The combination of ZFS’s reliability, modern containerization, and active development makes it an excellent foundation for any homelab.

Start Simple:

  • Begin with basic pool/dataset setup
  • Add complexity gradually
  • Test thoroughly before production
  • Document everything

Invest in Reliability:

  • UPS is non-negotiable
  • Redundancy is essential
  • Backups are your insurance policy
  • Monitoring enables proactive management

Plan for Growth:

  • Design for 2-3 years ahead
  • Leave room for expansion
  • Build relationships for remote backup
  • Keep learning and improving

Remember: Your data is valuable. ZFS protects against hardware failure, but only a complete backup strategy protects against all threats. Implement snapshots, replication, and offsite backups from day one.

Welcome to the TrueNAS community! Your homelab journey has just begun.


Additional Resources

Quick Reference Commands

# Pool status
zpool status

# Pool I/O statistics
zpool iostat -v 5

# Dataset list
zfs list

# Snapshot list
zfs list -t snapshot

# Create manual snapshot
zfs snapshot tank/storage@manual-$(date +%Y%m%d-%H%M%S)

# Restore file from snapshot
cp /mnt/tank/storage/.zfs/snapshot/SNAPSHOT_NAME/path/to/file /mnt/tank/storage/

# Check scrub progress
zpool status -v

# View ARC statistics
arc_summary

# Disk information
smartctl -a /dev/sda

# Network test
iperf3 -s  # Server mode
iperf3 -c 192.168.1.100  # Client mode

Emergency Contacts

TrueNAS Support:

Documentation:

Hardware Suppliers:

  • ServerPartDeals.com: Refurbished enterprise drives
  • LabGopher: Used server equipment deals
  • NewEgg/Amazon: Consumer drives and components

Document Version: 1.0 Created: 2025-12-16 Word Count: ~6,800 words Based on Research: TrueNAS comprehensive research guide Target Audience: Intermediate homelabbers

Feedback: Share your experiences and suggestions for improving this guide on the homelabbing.io community forums.