This guide walks through setting up a NixOS virtual machine in Unraid from scratch. The goal is a minimal, declarative server that you can use as a base for self-hosted services. We’ll cover creating the VM, partitioning the disk, installing NixOS with a sensible server configuration, and getting SSH access working.
NixOS uses a single configuration file to define the entire system — packages, users, services, networking. This means the setup is reproducible and can be version-controlled. Instead of running commands to install packages and edit config files across the system, everything lives in configuration.nix.
This guide is a simplified walkthrough based on the official NixOS installation manual, combined for x86_64, UEFI, and Unraid. Refer to the official docs for edge cases or alternative setups.
1. Download the NixOS minimal ISO#
This guide uses the x86_64 image. NixOS also provides an aarch64 (ARM64) build, but the steps below are written for x86_64.
Grab the minimal ISO image for x86_64 from the NixOS download page. Choose the latest minimal installer image and place the .iso file in your Unraid ISO share (typically /mnt/user/isos/).
2. Set up the Unraid VM#
Create a new VM in Unraid using the Linux template. I used the following settings but feel free to adjust them to your needs:
| Setting | Value |
|---|---|
| Firmware | UEFI (OVMF) |
| Machine type | pc-q35-10.2 |
| CPU | 2 vCPU, host-passthrough |
| Memory | 4096 MB |
| Disk bus | virtio (raw, writeback) |
| Network | virtio-net, bridged to br0 |
| ISO | nixos-minimal-x86_64-linux.iso |
This guide assumes a UEFI boot setup. The VM must use OVMF firmware — a BIOS/SeaBIOS VM will not work with the partition layout and boot loader configuration below.
3. Partition the disk#
Boot the VM from the ISO. You’ll be logged in as the nixos user — switch to root with sudo -i.
parted /dev/vda -- mklabel gpt
parted /dev/vda -- mkpart ESP fat32 1MB 512MB
parted /dev/vda -- set 1 esp on
parted /dev/vda -- mkpart root ext4 512MB 100%Check:
lsblkYou should see roughly:
vda
├─vda1 511M
└─vda2 <rest of disk>4. Format the partitions#
mkfs.fat -F 32 -n BOOT /dev/vda1
mkfs.ext4 -L nixos /dev/vda2No swap partition — for a self-hosted server the RAM allocation is predictable, so swap is rarely needed. You can always add a swap file later if a service requires it.
5. Mount the root filesystem#
mount /dev/disk/by-label/nixos /mntWe use the disk label (nixos) instead of /dev/vda2 so the mount survives disk order changes.
6. Mount the EFI partition#
mkdir -p /mnt/boot
mount -o umask=077 /dev/disk/by-label/BOOT /mnt/bootYou can verify:
lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINTSYou should see:
vda
├─vda1 vfat BOOT /mnt/boot
└─vda2 ext4 nixos /mnt7. Generate the NixOS configuration#
nixos-generate-config --root /mntThis auto-detects your hardware and creates two files:
/mnt/etc/nixos/configuration.nix # main config — you edit this
/mnt/etc/nixos/hardware-configuration.nix # auto-generated — leave as-is8. Edit the configuration#
nano /mnt/etc/nixos/configuration.nixReplace the entire file with this minimal but solid starting point for a VPS server:
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Use latest kernel.
boot.kernelPackages = pkgs.linuxPackages_latest;
networking.hostName = "nixos";
# NetworkManager is for desktops — disabled on a static server
networking.networkmanager.enable = false;
# Check the interface name with `ip link` before editing
networking.interfaces.enp1s0.useDHCP = true;
time.timeZone = "Europe/Berlin";
i18n.defaultLocale = "en_US.UTF-8";
users.users.flohoss = {
isNormalUser = true;
description = "Florian Hoss";
# wheel group grants sudo privileges
extraGroups = [ "wheel" ];
};
services.openssh.enable = true;
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 22 ];
environment.systemPackages = with pkgs; [
vim
wget
];
system.stateVersion = "26.05"; # Update this to match your NixOS version
}Replace the username and hostname with your own values. The interface name (enp1s0) may differ — check it with ip link before editing.
9. Install NixOS#
Once your configuration is ready:
nixos-install --root /mntIt will ask you to set/confirm the root password. Once the install finishes, you can unmount:
umount /mnt/boot /mnt10. Reboot#
rebootThen remove/disable the NixOS installer ISO in Unraid so the VM boots from /dev/vda.
After reboot, open the Unraid VNC console and set a password for your user:
passwd flohossYou can now log in via SSH with the password:
ssh flohoss@<vm-ip>Upload your SSH key so you can log in without a password:
ssh-copy-id -i ~/.ssh/id_ed25519.pub flohoss@<vm-ip>11. Harden SSH#
Now that your key is in place, disable password and root login. Edit the configuration on the VM:
sudo nano /etc/nixos/configuration.nixAdd the following inside the existing services.openssh block:
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};Rebuild and switch:
sudo nixos-rebuild switchWhy not put the key in the config? The key you uploaded with
ssh-copy-idlives in~/.ssh/authorized_keysin your home directory, whichnixos-rebuildnever touches — it only manages the system in the Nix store. So the key survives every rebuild. It would only be lost on a full disk wipe/reinstall.You might be tempted to declare the key directly in
configuration.nixviaopenssh.authorizedKeys.keys— the NixOS way. But the initial config is edited in the Unraid VNC console (step 8), where copy-paste is flaky at best (especially from macOS) — typing an entire SSH public key by hand is impractical.ssh-copy-idover SSH after the first boot is the reliable approach. You can always move the key into the config later for a fully declarative setup — by then you’re editing over SSH where paste works.
From now on you can only log in with your key — no passwords accepted over SSH. You’ll use the same sudo nixos-rebuild switch command after any future config change.
