Title: Install NixOS with ZFS and encrypted /home Author: Alexander Arkhipov Created: 2025-01-09 Modified: 2025-01-09 I recently bought a ThinkPad L430 specifically with the purpose of running a Linux distro on it (rather than my usual choice of OS, OpenBSD). After some thought I decided to install NixOS with ZFS root, and encrypted home dataset. This turned out to be a somewhat less explored area than I thought it might be, so here's my how-to guide for such installation. BOOT INTO INSTALLATION ENVIRONMENT I assume you know how to do this. If not, refer to the [NixOS Manual]. For the purposes of this guide, I used a non-graphical installer. You should be able to use an XFCE/KDE ISO, but you'll have to install the OS manually anyway. FIRST THINGS FIRST $ sudo su - # loadkeys dvorak Ahhh... much better. Also, make sure you network's alright. # ping nixos.org DISK SETUP Partition the disk as you normally would, creating a boot partition, swap and a single root partition. Then create the zfs pool, datasets and the swap partition. For zpool it is much better to use /dev/disk/by-id/* than plain /dev/*. # zpool create -O compression=zstd -O mountpoint=none -O xattr=sa \ > -O acltype=posixacl -o ashift=12 zroot /dev/disk/by-id/ata-MY_DISK_ID-part3 # zfs create zroot/ROOT # zfs create zroot/nix # zfs create zroot/var # zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt \ > zroot/home You can use zpool status and zfs list for double checking. Mount the zfs datasets. # mkdir -p /mnt # mount -t zfs zroot/ROOT /mnt -o zfsutil # (cd /mnt && mkdir nix var home) # for d in nix var home; do mount -t zfs zroot/$d /mnt/$d -o zfsutil; done And finally, mount the boot partition and enable swap. # mkfs.fat -F 32 -n BOOT /dev/disk/by-id/ata-MY_DISK_ID-part1 # mkdir /mnt/boot # mount -o umask=077 /dev/disk/by-id/ata-MY_DISK_ID-part1 /mnt/boot # mkswap -L swap /dev/disk/by-id/ata-MY_DISK_ID-part2 # swapon /dev/disk/by-id/ata-MY_DISK_ID-part2 INSTALLING NIXOS Generate the config as normal: # nixos-generate-config --root /mnt We need to edit /mnt/etc/nixos/hardware-configuration.nix: 1. Add options = [ "zfsutils" ]; for zfs mounts. 2. Add randomEncryption = true; in swapDevices. Like so: fileSystems."/" = { device = "zroot/ROOT"; fsType = "zfs"; options = [ "zfsutil" ]; # HERE }; fileSystems."/nix" = { device = "zroot/nix"; fsType = "zfs"; options = [ "zfsutil" ]; # AND HERE }; fileSystems."/var" = { device = "zroot/var"; fsType = "zfs"; options = [ "zfsutil" ]; # HERE TOO }; fileSystems."/home" = { device = "zroot/home"; fsType = "zfs"; options = [ "zfsutil" ]; # YOU GUESSED IT }; fileSystems."/boot" = { device = "/dev/disk/by-id/ata-MY_DISK_ID-part1"; fsType = "vfat"; }; # Make sure to use /dev/disk/by-id/ if enabling encryption swapDevices = [{ device = "/dev/disk/by-id/ata-MY_DISK_ID-part2"; randomEncryption = true; }]; In /mnt/etc/nixos/configuration.nix make sure to set: boot.zfs.devNodes = "/dev/disk/by-id"; # Generate hostid with: head -c4 /dev/urandom | od -A none -t x4 # (or whichever method you prefer) networking.hostId = "01234567"; And finally, run: # nixos-install # nixos-enter --root /mnt -c 'passwd myuser' # umount /mnt/boot && zpool export -a # Don't forget that if you want to boot # reboot [NixOS Manual] https://nixos.org/manual/nixos/stable/