The text 'Building a custom NixOS installer' over blurred lines of source code. There is a Nix Snowflake in the bottom right corner.

It's easier than you'd think!

Just a few days ago, I finally brought my old MacBook Pro (mid-2012 retina) back from the dead and, naturally, wanted to install Linux on it. My main distro being NixOS, that was the obvious choice. However, when I booted into the installer, I found that I had no networking available. After some digging, I found that it was because it needs proprietary Broadcom wi-fi drivers to connect to anything.

The standard NixOS installer is very dependent on an internet connection to download packages and configure your system, so how do you deal with that? Without a wi-fi connection (and no ethernet ports), it's not like I can just download the drivers either. Luckily, NixOS lets you build your own custom installer ISOs with a selection of packages available.

I found this GitHub issue that discusses solutions and provides a custom image you can use. The problem is that the provided image is for NixOS 17.03, which uses an older version of Nix (pre-2.0). At first I figured I could just perform the update during the installation or after, but due to the Nix version bump, I was unable to upgrade. Obviously, I had to take matters into my own hands.

Now that I knew I could build my own custom ISOs, I went looking for documentation on it and found the section in the manual and the wiki article. They're both pretty short, but that's because they don't need to be any longer: It's surprisingly easy and straightforward.

Simply create a Nix file that imports their installers and specifiy what packages you want available and any changes you want to make to the system.

The base config file they provide is this:

# This module defines a small NixOS installation CD.  It does not
# contain any graphical stuff.
{config, pkgs, ...}:
{
  imports = [
    <nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix>

    # Provide an initial copy of the NixOS channel so that the user
    # doesn't need to run "nix-channel --update" first.
    <nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
  ];
}

We can extend this to add our proprietary drivers and even additional packages to have available in the installer. So if you prefer the Fish shell to Bash or want to have access to Git? Yeah, we can do that.

{config, pkgs, ...}:
{
  imports = [
    <nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix>
    <nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
  ];

  # configure proprietary drivers
  nixpkgs.config.allowUnfree = true;
  boot.initrd.kernelModules = [ "wl" ];
  boot.kernelModules = [ "kvm-intel" "wl" ];
  boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];

  # programs that should be available in the installer
  environment.systemPackages = with pkgs; [
    fish
    git
  ];
}

Building the image is a simple command. Assuming your file is called iso.nix:

nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixos-config=iso.nix

And that's it. Now, just flash it onto a drive or burn it onto a disc and you're off to the races.


Before rounding out this post, there's a few things I think it's worth to be aware of, even if we won't look too much into them:

  • The wiki states that you don't need an internet connection when using a custom ISO with packages, which makes me think that if you specify in this config all the packages you'll need (for your final install), you won't need to download them again when actually installing.
  • nix-build will build the image based on your system's nixos Nix channel. I use the unstable branch, so it built an image based on a NixOS 19.09 preview. You can of course change channels in the installer if you want to use a different base for the install (though this would definitely require internet access).
  • From what I understand, you need a NixOS system to build one of these images. So if you need one of these but don't run NixOS already, it seems you're locked into finding someone who could build the image for you. This isn't great for onboarding new people, and you'd think that it'd suffice with just the Nix package manager---honestly: it might. I don't know---but the documentation talks specifically about building using "an existing working NixOS installation". As was pointed out to me on Reddit, you need the Nix package manager to build one of these images, but not necessarily a NixOS system. However, it was also mentioned that it does probably have to be a Linux system, so Nix on macOS likely wouldn't work.

And with that: goodbye!



Thomas Heartman is a developer, writer, speaker, and one of those odd people who enjoy lifting heavy things and putting them back down again. Preferably with others. Doing his best to gain and share as much knowledge as possible.