When I put together my homelab, I ran into dilemma with my storage setup, the hard drives I had were all different sizes and I didn’t want to lose usable space by forcing them into a traditional RAID configuration, I wanted something that would let me combine the drives into one logical pool, use the full capacity of each disk, but still give me some level of redundancy.

After a bit of research and trial and error, I settled on using MergerFS with SnapRAID. MergerFS lets the drives appear as a single mount point, while SnapRAID handles parity and recovery if a drive fails.

This is part 2 of my NAS setup, it was a long process spread out into multiple days.

Read the other parts:
Part 1: A DIY NAS with a Twist
Part 3: Automating SnapRAID Tasks

Part 2: Setting up MergerFS + SnapRaid

These are basically my notes in a somewhat structured way during the setup process of MergerFS and SnapRAID.

Step 1: The Virtual Machine Setup:

Note: I am running this in a Virtual Machine in Proxmox.

Install Ubuntu Server Minimal (24.04.4), start the virtual machine and update it:

sudo apt update && sudo apt upgrade -y

Reboot and install the needed packages:

sudo -i # become root
apt install -y curl smartmontools lm-sensors gdisk parted fuse3 xfsprogs

Check that all drives are seen by the VM and list all block devices and identify each drive:

lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,LABEL,UUID
# or for more detail:
sudo fdisk -l
# or using disk IDs (recommended for scripts):
ls -lh /dev/disk/by-id/

Step 2: Drives Set up:

Quick Note: If these drives already have data and were not in a RAID array, this step can be skipped.

For each data/parity drive (e.g. /dev/sdb, /dev/sdc, /dev/sdd) wipe the partition table and signatures:

sudo wipefs -a /dev/sdX          # remove all filesystem signatures
sudo sgdisk --zap-all /dev/sdX   # zap GPT and MBR partition tables

Format each drive, create a gpt partition table and single partition in each drive:

# Create GPT label
sudo parted -s /dev/sdX mklabel gpt

# Create a single partition using 100% of the drive
sudo parted -s /dev/sdX mkpart primary xfs 0% 100%

# Inform the kernel of partition table changes
sudo partprobe /dev/sdX

Create the filesystem:

# Format with XFS
sudo mkfs.xfs -f -L "disk1" /dev/sdX1   # data drive 1
sudo mkfs.xfs -f -L "parity1" /dev/sdZ1 # parity drive

Note: any file system works, xfs is used in this setup.

Step 3: Mount points:

Create the mount points for data and parity drives, fix folders ownership and write permissions:

# data disks mount location
cd /mnt 

# one mount per data and parity drives
sudo mkdir disk1 disk2
sudo mkdir ssd1 ssd2 ssd3
sudo mkdir parity1

# find your user and group id with "id" in terminal
sudo chown -R 1000:1000 disk* && sudo chmod -R 775 disk* 
sudo chown -R 1000:1000 ssd* && sudo chmod -R 775 ssd* 
sudo chown -R 1000:1000 parity1 && sudo chmod -R 775 parity1

Repeat for pooled storage:

Pooled storage mounted to /home/user/tank for the HHD pool and /home/user/fast for the SSD share.

# pool is mounted to home directory
cd ~ 
mkdir tank fast

Find each partition UUID to mount in /etc/fstab:

ls -lh /dev/disk/by-id/

Edit /etc/fstab and mount all partitions:

sudo nano /etc/fstab

Add to the end of the fstab file:

# Parity Disk1
UUID=61c45a69-e8e4-4f98-aa09-b7554a910495 /mnt/parity1 xfs    defaults,noatime,largeio,inode64,logbsize=256k,nofail    0    0

# Data disk 1 hhd1
UUID=a8815d32-a025-4667-bd17-0b01584e0334 /mnt/disk1 xfs    defaults,noatime,largeio,inode64,logbsize=256k,nofail    0    0

# repeat for all partitions:

Mount verify mount points are working:

# mount
sudo mount -a

# wait for the prompt and then run 
sudo systemctl daemon-reload

# verify mount points
df -h

It will look like this

# my drives already have data
/dev/sdc1        13T  2.9T   10T  23% /mnt/disk1
/dev/sdd1        13T  3.5T  9.3T  28% /mnt/disk2
/dev/sdb1        15T  3.6T   12T  25% /mnt/parity1

Step 4: Installing MergerFS and SnapRaid

sudo apt install mergerfs snapraid -y

Step 5: Storage Pools setup:

MergerFS uses policies to store data in the right locations, read the MergerFS Documentation for better understanding.\

Edit /etc/fstab and create the pools:

sudo nano /etc/fstab

Create two pools, one for HDDs and one for SSDs. Scroll down and add to the bottom:

# HHD Pool 
/mnt/disk*  /home/user/tank  fuse.mergerfs  cache.files=off,moveonenospc=true,category.create=epmfs,func.getattr=newest,minfreespace=50G,fsname=mergerfsPool  0  0

# SSD Pool 
/mnt/ssd*  /home/user/fast  fuse.mergerfs  cache.files=off,moveonenospc=true,category.create=epmfs,func.getattr=newest,minfreespace=50G,fsname=mergerfsPool  0  0

Mount the storage pools:

sudo mount -a

# wait for the prompt and run
sudo systemctl daemon-reload

# verify the mounts
df -h

Should look something like this:

mergerfsPool    3.7T  675G  3.0T  19% /home/user/fast
mergerfsPool     26T  6.4T   20T  25% /home/user/tank

Step 5: SnapRAID configuration

Create SnapRAID Configuration file:

# create the directory for the configuration file
sudo mkdir -p /var/snapraid

# create/edit the configuration file
sudo nano /etc/snapraid.conf

This is my configuration:

###############################################################################
# SnapRAID config (Ubuntu 24.04 + mergerfs)
###############################################################################

# Content files — one per data disk + parity + OS drive for maximum redundancy
# The OS copy is the most critical: survives any single data/parity drive loss
content /var/snapraid/snapraid.content
content /mnt/disk1/.snapraid.content
content /mnt/disk2/.snapraid.content
content /mnt/ssd1/.snapraid.content
content /mnt/ssd2/.snapraid.content
content /mnt/ssd3/.snapraid.content
content /mnt/parity1/.snapraid.content

# Parity
parity /mnt/parity1/snapraid.parity

# Data disks
data d1 /mnt/disk1/
data d2 /mnt/disk2/
data d3 /mnt/ssd1/
data d4 /mnt/ssd2/
data d5 /mnt/ssd3/

###############################################################################
# Excludes
###############################################################################

# Temp / scratch files
exclude *.unrecoverable
exclude *.tmp
exclude *.temp
exclude *.swp
exclude *.swo

# macOS — covers DS_Store, resource forks (._*), Spotlight,
# FSEvents, Trash, and legacy Apple DB directories
exclude .DS_Store
exclude ._*
exclude .AppleDouble/
exclude .AppleDB/
exclude .AppleDesktop/
exclude .Spotlight-V100/
exclude .fseventsd/
exclude .Trashes/
exclude .TemporaryItems/
exclude .VolumeIcon.icns
exclude .apdisk

# Windows
exclude Thumbs.db
exclude desktop.ini
exclude ehthumbs.db

# Linux desktop cache (Samba/NFS clients)
exclude .Trash-*/
exclude .thumbnails/
exclude .cache/

# System / filesystem
exclude lost+found/
exclude /tmp/
exclude /var/tmp/

# NAS metadata (Synology / other)
exclude @eaDir/
exclude @tmp/
exclude #recycle/

Why multiple .snapraid.content files? These files are used to track metadata and parity state, the more copies the better to recover in case of disk failure, these are small files and do not take much space (relatively speaking).

Step 6: Run first sync

Run the sync as root:

sudo -i
snapraid sync

Quick if no data saved, slow if enough data stored already. Note that on a full drive the first sync can take many hours, this is normal, let it complete.

After the first sync completes, run a scrub to verify parity before calling the setup complete:

snapraid scrub

All set, the next step from here is Automating SnapRAID Tasks

References: