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: