How to Build a Minimal ZFS NAS without Synology, QNAP, TrueNAS
How to Build a Minimal ZFS NAS without Synology, QNAP, TrueNAS
Published on: 2024-08-23
ZFS System by OracleIf you need a basic NAS and don't care about GUI features, it is suprisingly simple to set up a ZFS dataset and share it over the network using Samba.<br>Scope:
Scope & Requirements
Raid Level<br>RAIDZ1 (1 Drive Redundancy)
Operating System<br>Debian 12 Bookworm
Encryption<br>None
ZFS Implementation<br>OpenZFS, zfs-2.1.1
CPU<br>4 Cores, Xeon Server CPU can be had for cheap
RAM<br>ECC RDIMM RAM 16 GB
Storage<br>4x4TB NVMe SSD
Backups<br>Not covered, use ZFS Backup Scheduler
Skills<br>Basic familiarity with Linux
Skill Level<br>Beginner/Easy
I am using this article to document it for future myself, feel free to adopt it for your needs. Problem with TrueNAS is that it is a full-featured, supposedly enterprise-grade, software suite. While it may be simple to set it up (I've never tried), I just don't need any of the bells and whistles it offers. It's the mismatch between what I need and what it offers; not something inherently wrong with TrueNAS. There is also something to be said about a system you know everything about and not having to rely on yet another thing.<br>ZFS's best feature that's never explained or written anywhere<br>ZFS filesystem is self contained. If your OS is nuked suddently, simply take all disks to another machine or install a new OS, install zfs, run zfs import and get back your data. This freedom is underrated and not well understood. It is also not explained anywhere.<br>It's worth emphasizing: All configuration/details about ZFS is stored on the disks themselves. If you've setup a RAIDZ2 (Raid 6) with 6 disks, they are self contained. Move them to a new machine with zfs tools installed, and simply run zfs import. Boom, they'll show up as RAIDZ2. This is an amazing feature that no matter what happens to the host OS, machine, etc; as long as the disks are not damaged, your data is fine.<br>Step 1. Locate and Organize Disks<br>List all disks on a linux machine using lsblk -d -o TRAN,NAME,TYPE,MODEL,SERIAL,SIZE command.<br>[root@sys ~]# lsblk -d -o TRAN,NAME,TYPE,MODEL,SERIAL,SIZE<br>TRAN NAME TYPE MODEL SERIAL SIZE<br>sda disk Virtual disk 40G<br>nvme nvme5n1 disk Samsung SSD 990 PRO 4TB XXXXXXXXXXXXXXX 3.6T<br>nvme nvme2n1 disk Samsung SSD 990 PRO 4TB XXXXXXXXXXXXXXX 3.6T<br>nvme nvme6n1 disk Samsung SSD 990 PRO 4TB XXXXXXXXXXXXXXX 3.6T<br>nvme nvme3n1 disk Samsung SSD 990 PRO 4TB XXXXXXXXXXXXXXX 3.6TThese are brand new NVMe drives from Samsung so they should be completely unallocated.<br>The disks are also mapped to an ID, running ls -lh /dev/disk/by-id:<br>[root@sys ~]# ls -lh /dev/disk/by-id<br>total 0<br>lrwxrwxrwx. 1 root root 10 May 10 09:34 dm-name-rhel-root -> ../../dm-0<br>lrwxrwxrwx. 1 root root 10 May 10 09:34 dm-name-rhel-swap -> ../../dm-1<br>lrwxrwxrwx. 1 root root 10 May 10 09:34 lvm-pv-uuid-DGBpev-Na0C-tY20-YY6E-tpL3-epNA-8Ts3Y0 -> ../../sda3<br>lrwxrwxrwx. 1 root root 13 May 10 09:34 nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX -> ../../nvme2n1<br>lrwxrwxrwx. 1 root root 13 May 10 09:34 nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX -> ../../nvme5n1<br>lrwxrwxrwx. 1 root root 13 May 10 09:34 nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX -> ../../nvme3n1<br>lrwxrwxrwx. 1 root root 13 May 10 09:34 nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX -> ../../nvme6n1Notice that they are symlinked to their disk names in /dev/.<br>We can create a /etc/zfs/vdev_id.conf that maps an alias to these IDs:<br>[root@sys ~]# vim /etc/zfs/vdev_id.conf
# Add these lines in the vdev_id.conf file<br>alias nvme0 /dev/disk/by-id/nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX<br>alias nvme1 /dev/disk/by-id/nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX<br>alias nvme2 /dev/disk/by-id/nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXX<br>alias nvme3 /dev/disk/by-id/nvme-Samsung_SSD_990_PRO_4TB_XXXXXXXXXXXXXXXRun udevadm trigger to set the alias (or you can reboot the machine). We can verify that the aliases have been mapped by running ls -lh /dev/disk/by-vdev:<br>lrwxrwxrwx. 1 root root 13 May 10 10:28 nvme0 -> ../../nvme2n1<br>lrwxrwxrwx. 1 root root 13 May 10 10:28 nvme1 -> ../../nvme5n1<br>lrwxrwxrwx. 1 root root 13 May 10 10:28 nvme2 -> ../../nvme3n1<br>lrwxrwxrwx. 1 root root 13 May 10 10:28 nvme3 -> ../../nvme6n1Alias mapping is completely optional, you can if you'd like use the full ID /dev/disk/by-id/nvme-eui.002538414143c248 of the disk when creating the zpool as we will do in the next section. Using an alias makes it nice. However, please don't use /dev/nvme1, /dev/nvme2, ... as the order is not guaranteed, especially if you mount a new drive to the system. Creating a vdev_id.conf ensures that the serial number of the drive is tied to the alias.<br>Remember when we discussed there is no configuration needed on the host OS? /etc/zfs/vdev_id/conf is not necessary and only used when creating a zpool for convenience. If your OS gets nuked, and you lose vdev_id.conf, it won't matter at all.<br>Step 2. Create ZPOOL<br>For this tutorial, I am creating a RAIDZ1...