$linuxjunkies
>

How to Install NixOS

Install NixOS from scratch: partition disks, write configuration.nix, pick a channel, run nixos-install, and master the nixos-rebuild workflow for atomic system changes.

AdvancedUbuntuDebianFedoraArch12 min readUpdated June 7, 2026

Before you start

  • A USB drive of at least 2 GB and a way to write the ISO (dd, balenaEtcher, etc.)
  • Target machine with at least 40 GB of disk space and 2 GB of RAM
  • Wired Ethernet or knowledge of your WiFi credentials for the live environment
  • Basic familiarity with partitioning concepts (GPT vs MBR, EFI vs BIOS boot)

NixOS flips the traditional Linux install model on its head. Instead of imperatively running commands to configure your system, you declare the entire machine state in /etc/nixos/configuration.nix and let nixos-rebuild make it real. Every change is atomic and rollbackable. That power comes with a steeper learning curve — this guide gets you through a clean installation to a working, reproducible system.

What You Need Before You Start

Download the NixOS minimal ISO (or the graphical ISO if you want a live desktop to reference) from nixos.org/download. The minimal ISO is smaller and forces you to learn the config early, which pays off. Burn it to a USB drive with dd or a tool like balenaEtcher, then boot your target machine from it.

Partition and Format the Disk

NixOS has no guided partitioner in the minimal ISO. You do this by hand. The example below targets /dev/sda on a UEFI system using a simple two-partition layout (EFI + root). Adjust the device path to match your hardware — check with lsblk first.

lsblk

Create the partition table:

parted /dev/sda -- mklabel gpt
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
parted /dev/sda -- set 1 esp on
parted /dev/sda -- mkpart primary 512MiB 100%

Format both partitions:

mkfs.fat -F 32 -n boot /dev/sda1
mkfs.ext4 -L nixos /dev/sda2

If you prefer btrfs or XFS, substitute accordingly — NixOS supports both fully. For a BIOS/MBR system, swap the GPT label for msdos, skip the ESP partition, and create a single root partition with the boot flag.

Mount the Filesystems

NixOS's installer generates your initial config from the currently mounted layout, so mount everything before running nixos-generate-config.

mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot

Generate the Initial Configuration

This command inspects your hardware and mounted filesystems, then writes two files: configuration.nix (system config) and hardware-configuration.nix (auto-detected hardware — treat this as read-only).

nixos-generate-config --root /mnt
ls /mnt/etc/nixos/
# hardware-configuration.nix  configuration.nix

Edit configuration.nix

Open the main config with any editor available on the live ISO (nano is always present; vim may need nix-shell -p vim first).

nano /mnt/etc/nixos/configuration.nix

The generated file is heavily commented. Here is a practical baseline to work from — read every option, they are all meaningful:

{ config, pkgs, ... }:

{
  imports = [ ./hardware-configuration.nix ];

  # Bootloader — systemd-boot for UEFI, GRUB for BIOS
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # Hostname
  networking.hostName = "mymachine";

  # Enable NetworkManager for easy WiFi/Ethernet management
  networking.networkmanager.enable = true;

  # Locale and timezone
  time.timeZone = "America/New_York";
  i18n.defaultLocale = "en_US.UTF-8";

  # Desktop environment (remove if you want headless)
  services.xserver.enable = true;
  services.xserver.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Enable sound via PipeWire (modern default)
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    pulse.enable = true;
  };

  # Define a user account
  users.users.alice = {
    isNormalUser = true;
    extraGroups = [ "wheel" "networkmanager" ];
    initialPassword = "changeme";
  };

  # Allow wheel group to use sudo
  security.sudo.wheelNeedsPassword = true;

  # System packages available to all users
  environment.systemPackages = with pkgs; [
    vim
    git
    wget
    curl
    htop
  ];

  # OpenSSH — enable if you need remote access
  services.openssh.enable = true;

  # NixOS release that this config was written for.
  # Do NOT change this after the first install.
  system.stateVersion = "24.11";
}

Important: The system.stateVersion field is not the version you want to run — it records the NixOS version present when you first installed. Do not bump it on upgrades. It controls stateful data migrations only.

Choosing a Channel

NixOS channels determine which package set you pull from. The two main options are:

  • nixos-24.11 (or current stable) — well-tested, recommended for most machines.
  • nixos-unstable — rolling, near-latest packages, higher breakage risk.

Check and set the channel from inside the live environment:

nix-channel --list
# nixos https://nixos.org/channels/nixos-24.11

To switch to unstable instead:

nix-channel --add https://nixos.org/channels/nixos-unstable nixos
nix-channel --update

Stick with the stable channel for a first install. You can always switch after booting into the installed system.

Run the Installation

With the config written and the channel set, install the system:

nixos-install

This will download several hundred megabytes to gigabytes of packages depending on your config. At the very end it will prompt you to set a root password — do it. You can disable root login via SSH afterwards in config.

When it finishes without errors:

reboot

Remove the USB drive when the BIOS/UEFI screen appears.

First Boot and Verification

Log in as your user (password is whatever you set in initialPassword — change it immediately with passwd). Then confirm the system is healthy:

systemctl --failed
# Should return: 0 loaded units listed
nixos-version
# Example output: 24.11.20250401.abc1234 (Vicuna)

Making Changes: The nixos-rebuild Workflow

This is the core NixOS loop. Edit /etc/nixos/configuration.nix, then apply:

sudo nixos-rebuild switch

switch builds and activates immediately. If something goes wrong, reboot and select the previous generation from the bootloader menu — every nixos-rebuild switch creates a new boot entry automatically.

To test a config without making it the default boot entry, use:

sudo nixos-rebuild test

To build without activating (verify it compiles cleanly):

sudo nixos-rebuild build

Troubleshooting

nixos-install fails with "out of disk space"

The Nix store is written to /mnt/nix/store. Make sure your root partition has at least 20 GB free. A minimal headless system uses around 4–6 GB; GNOME adds considerably more.

System boots but has no network

Verify networking.networkmanager.enable = true is in your config and your user is in the networkmanager group. Run sudo nixos-rebuild switch after fixing, or check systemctl status NetworkManager.

Wrong bootloader type selected

If you used systemd-boot on a BIOS system (or GRUB on a system that boots in UEFI-only mode), the install will succeed but the machine won't boot. Re-mount from the live ISO, fix the bootloader options in configuration.nix, and re-run nixos-install. No other steps needed — nixos-install is idempotent.

A package is not found

Search the package database before editing config:

nix search nixpkgs firefox

If nix search is unavailable on your channel setup, use search.nixos.org/packages in a browser instead.

tested on:nixos 24.11

Frequently asked questions

Can I use Flakes instead of channels for a first NixOS install?
Yes, but Flakes require an extra mental model (flake.nix, flake.lock, the nixos-rebuild --flake flag) and are still marked experimental. Master the channel-based workflow first, then migrate — the concepts transfer directly.
What happens if I break my configuration and can't boot?
Every nixos-rebuild switch creates a numbered generation entry in the bootloader. At the GRUB or systemd-boot menu, select an earlier generation, boot into it, fix configuration.nix, and run nixos-rebuild switch again.
How do I install per-user packages without putting them in configuration.nix?
Use nix-env or, better, Home Manager. Home Manager lets you declare per-user packages and dotfiles in a separate home.nix file using the same declarative style as the system config.
Does system.stateVersion need to match my current NixOS channel version?
No. Set it once at install time and never change it. It only controls how NixOS handles migrations for stateful data (like database formats). Changing it to match the channel version is a common mistake that can corrupt state.
How large does the root partition need to be?
40 GB is a comfortable minimum for a desktop system with a few applications. The Nix store keeps multiple generations of every package; use nix-collect-garbage -d periodically to reclaim space from old generations.

Related guides