Background

I use NixOS as my main OS in everything (from personal laptop to my server), but I was beginning to miss Windows for gaming. (WINE won’t cut it here.) As a result, I went searching for installing Windows alongside an existing NixOS installation, but I couldn’t find one anywhere. I decided to just dive in, and it worked! Here is a high-level list of the steps I took. For reference, I am installing this on an XPS 9550, with EFI.

Before continuing on, you will need a live USB stick that has the NixOS installation media.

Steps

  1. Change the boot method from the default systemd-boot bootloader to GRUB. This will allow us to add Windows to the boot menu in the future. Here are the steps. For now, leave out the entire extraEntries line – we’ll add that later.
  2. If you need to resize NixOS:
    1. Boot into the live USB stick.
    2. Over-downsize your filesystem: resize2fs /dev/sdXY $something_smaller_than_new_size, where the size we input is something smaller than the final size of our partition we want.
    3. Shrink the actual partition:. Note that we first overshoot our shrink for the filesystem and then fit it back. This is to ensure that our partition doesn’t cut off our filesystem, which can lead to data loss.
      1. Start parted: parted --align optimal /dev/sdX
      2. List out partitions: (parted) print
      3. Shrink the right partition: (parted) resizepart number end
    4. Grow the filesystem to fill the entire space of the partition: resize2fs /dev/sdXY
  3. Install Windows. This is actually pretty simple; in the installer, simply click on the unallocated space to install Windows, and it’ll just work. magic!
  4. Now, your computer should be booting directly into Windows. We have to reinstall GRUB as the bootloader to fix that:
    1. Boot into the live USB stick.
    2. Mount your NixOS system onto /mnt. If you followed the instruction manual, then it would look like this:
      1. mount /dev/disk/by-label/nixos /mnt/
      2. mount /dev/disk/by-label/boot /mnt/boot
      3. swapon /dev/disk/by-label/swap
    3. Add all of your nix-channels that you currently use in your OS with nix-channel --add .... If you forgot, you can nixos-enter into your installation to check via nix-channel --list.
    4. Grab the UUID of boot partition via blkid, and add that in to the GRUB section of your configuration.nix. It should be located at /mnt/etc/nixos/configuration.nix. This is the part where we add Windows into GRUB.
    5. Rederive NixOS: nixos-install.

And then you should be done!

Things I Tried That Failed

  • Live booting the Nixos ISO, and trying to chroot into that environment to nixos-rebuild switch. This failed due to some strange error about being unable to write to the filesystem.
  • Live booting from Ubuntu to try to rebuild grub there. This failed because it requires either a chroot or directly specifying the EFI directory, and the chroot fails because Nixos doesn’t have a /bin/bash, and the EFI directory approach failed for some unknown reason.