Skip to content

Chapter 6 - Preparing For Install

Ok! We’re familiar with Nix and NixOS. Now let’s get ready to make the full switch.

In this chapter we will…

  1. Prepare our config to run on a real system
  2. Create a new config for a custom installation ISO
  3. Generate the installation ISO
  4. Flash the ISO to install media

Housekeeping Beforehand

Before anything, make sure you commit to your repo.

After that, I’d recommend deleting the nixos.qcow2 VM image from your folder and booting the VM again. This is to check your system from a blank slate and make sure you didn’t imperatively configure something you wanted.

Double-check that everything is how you want it without any previously configured state. This way we know that when you start up the system for the first time it’ll be exactly how you expect it.

Preparing our Config

Okay, first things first we’ll need a bootloader for our system. Since until now we’ve only run with the VM, we haven’t needed one. You’ll want to set boot.loader.systemd-boot.enable equal to true. This will ensure a bootloader exists when installing (The VM will still work with this set).

config.nix
boot.loader.systemd-boot.enable = true;

Also, if you’re device will be on WiFi make sure to enable wireless networking.

config.nix
networking.networkmanager.enable = true;
# or networking.wireless.iwd.enable
# or networking.wireless.enable
# up to you

Now, make sure to remove password under users.users.YOURNAME. This was just for testing and we don’t want this set now. You’ll be able to change your password after install.

config.nix
users.users.YOURNAME = {
# ...
password = "asdf";
# ...
};

Adding NixOS Hardware

NixOS hardware is a flake maintained by the NixOS community that contains various config settings that improve the NixOS experience on different devices.

Take a look at the repo and see if your computer’s model is there as a .nix file. If it is we can add it to your config.

  1. Add nixos-hardware as an input
    flake.nix
    {
    inputs = {
    # ...
    nixos-hardware.url = "github:NixOS/nixos-hardware"; # No nixpkgs input, don't need to override.
    };
    outputs = inputs @ {
    self,
    nixpkgs,
    home-manager,
    nix-index-db,
    nixos-hardware,
    }: {} # ...
    }
  2. Add your computer’s module to modules (I’ll add the Lenovo ThinkPad T430 as an example).
    flake.nix
    nixosConfigurations.YOURNAME = nixpkgs.lib.nixosSystem {
    # ...
    modules = [
    ./modules/config.nix
    # ...
    nixos-hardware.nixosModules.lenovo-thinkpad-t430
    ];
    };

Your config should now be tweaked to work well with your hardware configuration.

Nvidia Note

Handy Utilities

Next I’m going to recommend some basic programs to have installed on your system in the event there’s issues:

  • vim (or another buffer editor)
  • comma (so you can get any command you may need)

Of course none of these are required, but for recovering a system it may help.

Finally, we’ll run a check to make sure the system is sound.

Terminal window
nix flake check

Creating an Installation ISO

So, we could go ahead and download the official installer ISO from nixos.org. But…

  1. That installer uses channels (not flakes, yuck!)
  2. It’s a graphical installer (boring!)
  3. It’s more in the spirit of NixOS to make our own!

So instead we’re going to leverage yet another amazing NixOS feature to generate an installer ISO just for us.

Adding the Config

To start off you’ll need a new nixosConfigurations output in flake.nix. You can call this something like iso. This should be effectively a copy of your main NixOS config, except for modules.

flake.nix
outputs = inputs @ {
self,
nixpkgs,
# ...
}: ... {
# ...
nixosConfigurations.iso = nixpkgs.lib.nixosSystem {
inherit system pkgs;
specialArgs = { inherit inputs; };
modules = [
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" # I'll explain this in a sec
./modules/nix.nix # We want certain Nix features when installing, specifically flakes
./iso.nix # Suggested path, we'll make this in a sec, change as wanted
];
};
}

The first item we have is a reference to a module within nixpkgs. This module is what the official installer is also based on, it lets us create an ISO of this NixOS config.

Configuring the ISO

Now create and open ./iso.nix (or wherever you wish to place the ISO NixOS module), and fill out the boilerplate.

  • flake.nix
  • flake.lock
  • iso.nix
  • Directorymodules/
  • Directoryhome/
iso.nix
{pkgs, ...}: {
}

In here we’ll need some basic setup for our disk image.

iso.nix
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
gptfdisk # For partitioning disks
util-linux # Various utilities
vim # For editing things (you **will** need an editor!)
];
}

Now we’re going to include our own flake within the installer image. To do this we can use the special input self, which is a reference to our own flake.

iso.nix
{inputs, pkgs, ...}: {
environment.systemPackages = with pkgs; [
gptfdisk # For partitioning disks
util-linux # Various utilities
vim # For editing things (you will need an editor!)
];
environment.etc."flake".source = inputs.self;
}

This configures a symlink in etc called flake (put in quotes here to help get across that this can be any arbitrary string, you don’t need the quotes). We’re setting the source of this link to inputs.self. Which will tell Nix to make a copy of our Flake and place it in the Nix store, then return the store path.

By doing this we’re exposing the flake within the installer, we’ll use this to build the full system when installing.

Building the ISO

Now we’re ready to build. Similar to the VM, NixOS creates a package for every configuration that builds an ISO image of the config.

Terminal window
nix build .#nixosConfigurations.iso.config.system.build.isoImage

After a few minutes of building and compressing, the command should complete. In ./result/iso you should see your installed image generated! Now it’s time to flash it.

  • flake.nix
  • flake.lock
  • Directoryresult/
    • Directoryiso/
      • nixos-24.11.20241105.[hash]-x86_64-linux.iso

Flashing to a Thumbdrive

Find a flash drive, if you already know how to flash an ISO to make a thumbdrive bootable go ahead.

Now try to find the device under /dev. Most USB devices will be /dev/sdX where X is a letter. Keep in mind your own hard drive may be /dev/sdX as well, so be careful!.

To help find it, you can use the lsblk command to list all block devices. The device we want should not have a mount point.

Terminal window
lsblk

After determining the device path, you can run dd to copy the ISO image to the flash drive. Let’s say I have the following setup:

  • My installer drive is on /dev/sdX
  • My installer ISO is in /home/user/my-nixos-system/result/iso/nixos.iso (this will be different for you as the ISO name includes a hash). Make sure to do an absolute path here.

Using this setup I would use dd like so.

Terminal window
sudo dd if=/home/user/my-nixos-system/result/iso/nixos.iso of=/dev/sdX bs=4096 status=progress

This will copy the image in 4096-byte blocks to the flash drive, wait for the copying to fully finish.

After copying, the drive may re-mount depending on your system, eject the flashdrive and then unplug it.

We now have our very own custom installation ISO!

Final Prep

We’re now (finally) ready to install NixOS!