NixOS Home Server Series - Part 1
I have used various setups for my home server, currently I am running with OpenMediaVault . It’s a pretty good solution, but I don’t love the UI and and it can a bit bloated and clunky at times.
Why NixOS?
NixOS is a Linux distribution based on the Nix package manager. Known for its declarative configuration model, which allows you to define your entire system configuration in a single file.
This is the killer feature for me. If I made a change 2 years ago, it will be self documented in the config file. I can see what I did, and if I need to revert I just roll back to a previous version.
The Plan
To remove the complexity barrier of hardware we will be using a Virtual Machine with a simple a setup as possible. And no Nix flakes! At least for now.
Here’s what I want to start off with:
- booting this headless system
- setting up a basic hard drive layout with redundancy in mind
- 2x NVME boot drives in RAID 1
- 2x SATA SSD drives in RAID 1 (Storage)
- 2x SATA HDD drives in RAID 1 (Backup)
- A Samba Fileserver running
- SSH server running
Let’s go!
Download the minimal NixOS ISO from the NixOS download page, create a new VM in VMware Fusion, attach the ISO and setup virtual drives as above.
Start the VM, and boot into the console to create partitions and filesystems.
Open terminal and switch to root user:
sudo -iSetup the partitons.
# OS Disks (RAID1) for disk in /dev/nvme0n1 /dev/nvme0n2; do parted $disk mklabel gpt parted $disk mkpart ESP fat32 1MiB 512MiB parted $disk set 1 esp on parted $disk mkpart primary btrfs 512MiB 100% done# Storage (RAID1) for disk in /dev/sda /dev/sdb; do parted $disk mklabel gpt parted $disk mkpart primary btrfs 1MiB 100% done# Backup (RAID1) for disk in /dev/sdd /dev/sde; do parted $disk mklabel gpt parted $disk mkpart primary btrfs 1MiB 100% doneFormat Filesystems
# EFI System Partition (ESP) mkfs.fat -F32 -n BOOT /dev/nvme0n1p1 # OS Disk (RAID1) mkfs.btrfs -m raid1 -d raid1 /dev/nvme0n1p2 /dev/nvme0n2p2 -L NIXOS-ROOT # Create Btrfs subvolumes mount /dev/disk/by-label/NIXOS-ROOT /mnt btrfs subvolume create /mnt/@root btrfs subvolume create /mnt/@nix btrfs subvolume create /mnt/@home umount /mnt # Storage Pool (RAID1) mkfs.btrfs -m raid1 -d raid1 /dev/sda1 /dev/sdb1 -L STORAGE-POOL # Backup Pool (RAID1) mkfs.btrfs -m raid1 -d raid1 /dev/sdd1 /dev/sde1 -L BACKUP-POOLMount Filesystems
# Mount OS subvolumes mount -o subvol=@root,compress=zstd,noatime /dev/disk/by-label/NIXOS-ROOT /mnt mkdir -p /mnt/{boot,nix,home,storage,backup} mount -o subvol=@nix,compress=zstd,noatime /dev/disk/by-label/NIXOS-ROOT /mnt/nix mount -o subvol=@home,compress=zstd,noatime /dev/disk/by-label/NIXOS-ROOT /mnt/home # Mount boot partition mount /dev/disk/by-label/BOOT /mnt/boot # Mount storage and backup pools mount -o compress=zstd,noatime /dev/disk/by-label/STORAGE-POOL /mnt/storage mount -o compress=zstd,noatime /dev/disk/by-label/BACKUP-POOL /mnt/backupConfigure NixOS
nixos-generate-config --root /mntEdit Configuration
vim /mnt/etc/nixos/configuration.nix{ config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; # Boot loader configuration boot.loader = { efi = { canTouchEfiVariables = true; efiSysMountPoint = "/boot"; }; systemd-boot.enable = true; }; # Explicitly configure boot partition fileSystems."/boot" = lib.mkForce { device = "/dev/disk/by-label/BOOT"; fsType = "vfat"; }; # Filesystem RAID configuration for storage and backup pools fileSystems."/storage" = lib.mkForce { device = "/dev/disk/by-label/STORAGE-POOL"; fsType = "btrfs"; options = [ "compress=zstd" "noatime" ]; }; fileSystems."/backup" = lib.mkForce { device = "/dev/disk/by-label/BACKUP-POOL"; fsType = "btrfs"; options = [ "compress=zstd" "noatime" ]; }; # Networking and SSH networking.hostName = "nixos"; services.openssh = { enable = true; settings = { PasswordAuthentication = true; # Temporary for initial setup. PermitRootLogin = "yes"; # Temporary for initial setup. }; ports = [22]; }; networking.firewall.allowedTCPPorts = [22]; # Time zone setup. time.timeZone = "Europe/London"; # User configuration. users.users.root.initialPassword = "temp"; users.users.admin = { isNormalUser = true; extraGroups = [ "wheel" ]; initialPassword = "temp"; }; environment.systemPackages = with pkgs; [ vim # Vim text editor. ]; }Install NixOS
nixos-install /mntReboot
ssh admin@<ip>Post-Installation
# Change root password. passwd passwd admin # Harden SSH vim /etc/nixos/configuration.nixservices.openssh = { enable = true; settings = { PasswordAuthentication = false; # Disable password authentication. PermitRootLogin = "no"; # Disable root login. }; };# Rebuild NixOS configuration. nixos-rebuild switch# Verify Setup # Check mounted filesystems findmnt | grep storage && findmnt | grep backup && findmnt | grep boot # Check RAID status btrfs filesystem show btrfs device stats /storage btrfs device stats /backup btrfs device stats /boot btrfs device stats /mnt
And that’s a wrap for round 1. 😎
Apr 20, 2025