TrueNAS: Complete Storage Setup and Management Guide
Build enterprise-grade storage for your homelab. ZFS, snapshots, replication, and network shares.
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 (Debian Linux-Based) - RECOMMENDED
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
| Feature | CORE | SCALE |
|---|---|---|
| Base OS | FreeBSD | Debian Linux |
| RAM Minimum | 8 GB | 16 GB |
| CPU Recommendation | 2+ cores | 4+ cores |
| Virtualization | Bhyve | KVM |
| Containers | Jails | Docker/Compose |
| Development Status | Security patches | Active development |
| Recommended For | Storage-only | Multi-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 RAID-Z2 (Like RAID-6) - RECOMMENDED
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
- Use whole disks: ZFS works best with complete drives
- Allocate sufficient RAM: Minimum 1GB per 1-2TB usable storage
- Separate boot from data: Install OS on separate small SSD
- Avoid hardware RAID: TrueNAS needs direct disk access
- Plan redundancy upfront: Adding redundancy later is difficult
- Monitor pool health: Regularly check for degraded vdevs
- 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
- Insert USB stick and boot from it
- Select “Install/Upgrade”
- Choose destination disk (your boot SSD/USB)
- Confirm destructive action
- Set swap size (default is usually fine)
- Select UEFI boot loader (recommended for modern systems)
- Complete installation (5-10 minutes)
- 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:
- Accept EULA
- Set strong admin password
- Configure timezone and date/time
- Set hostname (e.g., “truenas-homelab”)
- Configure DNS servers (1.1.1.1, 8.8.8.8)
- 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:
- 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 - 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 - Set Up Alert Services:
System → Alert Services
Add notification method:
- Email (SMTP)
- Slack webhook
- Custom webhook
- PagerDuty - 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:
- Redundancy level (RAID-Z1, Z2, or Z3)
- Pool name (simple, lowercase: tank, storage, media)
- Hot spare configuration
- 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
| Feature | SMB | NFS | iSCSI |
|---|---|---|---|
| Protocol Type | File-level | File-level | Block-level |
| Best For | Windows users | Linux servers | VMs, databases |
| Performance | Good | Excellent | Excellent |
| Setup Complexity | Low | Medium | High |
| Windows Support | Native | Third-party | Native |
| macOS Support | Native | Native | Limited |
| Linux Support | Native | Native | Native |
| Multiple Writers | Yes | Yes | No (single host) |
| Recommended Priority | High | High | If 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:
- 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 - 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 - 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 - 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:
- Primary copy: Live data on TrueNAS pool
- Second copy: Local snapshots on same pool
- 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 (>90 days), benefit from higher compression',
'estimated_savings': '30-40%'
})
elif used / (used + available) > 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 > 0.7 else 'MEDIUM' if x > 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 < 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 < 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 <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 <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:
- TrueNAS SCALE is the recommended choice for modern homelabs
- ZFS provides enterprise-grade data protection
- RAID-Z2 offers best balance for most deployments
- Multi-tier backup strategy is essential (snapshots + replication + offsite)
- Docker integration enables powerful application hosting
- AI workloads thrive on TrueNAS storage
- 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:
- TrueNAS Documentation: truenas.com/docs
- TrueNAS Community Forums: truenas.com/community
- OpenZFS Documentation: openzfs.org
- Level1Techs Forums: forum.level1techs.com
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:
- Community Forums: truenas.com/community
- Discord: TrueNAS official server
- Reddit: r/truenas
Documentation:
- Official Docs: truenas.com/docs
- OpenZFS: openzfs.org
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.