Skip to content

Instantly share code, notes, and snippets.

@lesserfish
Last active July 5, 2025 04:03
Show Gist options
  • Select an option

  • Save lesserfish/8c0cfc6bb07c17c5af8a3759d2eb9e9a to your computer and use it in GitHub Desktop.

Select an option

Save lesserfish/8c0cfc6bb07c17c5af8a3759d2eb9e9a to your computer and use it in GitHub Desktop.
Setting up NixOS with impermanence!

Nix OS with impermanence

The following steps describe how to set up NixOS with impermanence using a ZFS drive.

Getting an initial configuration file

The configuration file generated by nixos-generate-config is quite barebones. If you are comfortable creating the initial configuration.nix file yourself, feel free to skip these steps.

  1. Run the NixOS installer normally. Install NixOS on your entire hard drive.

  2. Once finished, do NOT restart

  3. Run the following command to discover where the new system is mounted at

     > sudo mount
    
  4. It will say it is mounted somewhere in /tmp/PATH/TO/NIX. Simply copy the configuration file to your local path.

     > sudo cp /tmp/PATH/TO/NIX/etc/nixos/configuration.nix ~/configuration.nix
    
  5. Umount the partition

     > sudo umount /tmp/PATH/TO/NIX
    

Partitioning

  1. Use gparted or whatever partitioning software you are comfortable with. Make sure to use a GPT table if you plan on using UEFI. Create two partitions

    a) A 1024 MB FAT32 partition with the boot flag set up. we will refer to this partition as /dev/sdaX

    b) A secondary partition with the remaining space. We will refer to this partition as /dev/sdaY

  2. Use the following command to format /dev/sdaY as a ZFS partition

     > sudo zpool create -O encryption=on -O keyformat=passphrase -O keylocation=prompt -O compression=on -O mountpoint=none -O xattr=sa -O acltype=posixacl -o ashift=12 zpool /dev/sdaY
    
  3. Create the following datasets

     > sudo zfs create -o mountpoint=legacy zpool/root
     > sudo zfs create -o mountpoint=legacy zpool/home
     > sudo zfs create -o mountpoint=legacy zpool/nix
     > sudo zfs create -o mountpoint=legacy zpool/persist
    
  4. Mount the data sets

     > sudo mount -t zfs zpool/root /mnt
     > sudo mkdir /mnt/{home,boot,nix,persist}
     > sudo mount -t zfs zpool/home /mnt/home
     > sudo mount -t zfs zpool/nix /mnt/nix
     > sudo mount -t zfs zpool/persist /mnt/persist
     > sudo mount /dev/sdaX /mnt/boot
    
  5. Generate the configuration files.

     > sudo nixos-generate-config --root /mnt
    
  6. Replace the configuration file with the one we created previously (Optional)

     > sudo mv /mnt/etc/nixos/configuration.nix /mnt/etc/nixos/generated-config.nix
     > sudo cp ~/configuration.nix /mnt/etc/nixos/configuration.nix
    

Modifying the configuration.nix file

  1. Open /mnt/etc/nixos/configuration.nix in VIM or whatever text editor you are used to.

  2. In a new shell run mkpasswd and input your main user password.

  3. Copy the resulted hash to users.users.<name>.hashedPassword. Your configuration file wii have a section that looks like this:

    users.users.NixUser = {
       isNormalUser = true;
       description = "NixUser";
       extraGroups = ["networkmanager" "wheel"];
       hashedPassword = "$y$j9T$Aopi3TtDi/f6D25EwYFfu.$8gK/P9EtGoENVT6jCJ1DUu6Pg/0a9/dc/81lmNsinwA";
    }
    
  4. In a shell run head -c 8 /etc/machine-id

  5. Copy the resulted string to networking.hostId. It should look something like

       networking.hostId = "abcdabcd";
    
  6. Add the following to the file

       boot.loader.grub.zfsSupport = true;
    
  7. Remove boot.loader.systemd-boot.enable = true; config if added by nixos-generate-config.

  8. If you want to set up your system with UEFI instead of BIOS, set boot.loader.grub.device to nodev and boot.loader.grub.efiSupport to true.

        boot.loader.grub.device = "nodev";
        boot.loader.grub.efiSupport = true;
    
  9. Open /mnt/etc/nixos/hardware-configuration.nix in VIM or any other text editor, and make sure the /persist file system is set as neededForBoot. It should look something like this:

      fileSystems."/persist" =
          { device = "zpool/persist";
            fsType = "zfs";
            neededForBoot = true;
          }
    
  10. There seems to be a bug, where one of the settings for ZFS is set incorrectly. Check the name of the directory from which to import ZFS devices. This is possibly /dev/disk/by-uuid/. You can check by doing ls -l /dev/disk/by-uuid/ and checking whether or not there is a link to /dev/sdaY in there. Once you found it, set boot.zfs.devNodes to this value. It should look something like

        boot.zfs.devNodes = "/dev/disk/by-uuid";
    

Installing NixOS

We are finally ready to install NixOS. Simply run

      > sudo nixos-install 

Hopefully, It will take a minute before it finishes and you will be asked to set up the root password. Do not restart yet.

Setting up snapshots and impermanence

  1. We are going to create a backup from the root directory right after installation. To do that run

     > sudo zfs snapshot zpool/root@blank
    
  2. You can now reboot your system. It will launch into your newly installed NixOS.

  3. Login with your user, and open /etc/nixos/hardware-configuration.nix.

  4. Add the following lines to the file:

       boot.initrd.postDeviceCommands = lib.mkAfter ''
          zfs rollback -r zpool/root@blank
        '';
    
  5. Run sudo nixos-rebuild switch

Setting up permanence

Congratulations. You now have an impermanent system. It preserves /home and /persist across reboots, but everything else will be wiped out. You will need to 'opt-in' to preserve file systems across reboot. Be careful rebooting now as your configuration files will be deleted. Be sure to set up permanence first.

In order to do this, you can use the NixOS impermanence module.

You can also find some more info right here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment