How to run nix on qubes without crying (much)
Nix is great for keeping your system clean and your sanity slightly intact. But thanks to how QubesOS handles templates and persistence, it’s not plug-and-play.
Though you could just use a StandaloneVM, using Nix on an AppVM is more secure because no software would be able to establish persistence without you manually installing it in the TemplateVM.
For the same reason, we can’t just install Nix in an AppVM because the installer creates a folder in the root of our system (it creates the /nix folder), and the only persistent folders on an AppVM are /home and /rw. So it will vanish from existence on reboot.
Basically, a TemplateVM is an air-gapped VM whose contents get copied to an AppVM on startup, except for those two folders mentioned where configurations, app data, and your files are stored.
Creating TemplateVM
Because 99.9% of our packages and configs are going to be managed by Nix, I recommend setting up a minimal distribution to save space.
If you don’t already have one, download a minimal TemplateVM. It’s optional, and you will even save yourself a lot of sanity if you just install a normal template with a bit of memory overhead, but we’ll go with the debian-12-minimal option. 
Select debian-12-minimal or debian-12-xfce. The difference is that debian-12-xfce contains all essentials for actually using the system, while debian-12-minimal gives you a terminal.

Then create a TemplateVM qube that clones the TemplateVM you copied. From now on, I will refer to that VM as nix-template.
Then create an AppVM that will use nix-template as its base. 
Minimal templates won’t have working audio by default. See the fix here
Enabling network on TemplateVM
Because TemplateVMs are air-gapped (for good), to actually download the Nix installer, we would need to enable internet access on our nix-template, which is a security risk. It would be more secure to configure tinyproxy to only allow connections to the Nix server, though I didn’t find a way to do it yet. If you know how, let me know.
Go to nix-template settings and give it access to the sys-firewall net qube. 
Installing Nix
Now go to nix-template and install Nix with the following:
If you are on a minimal template, you might find out you don’t have curl installed. In that case, install it with apt. Also, you might want to install a terminal with clipboard support, such as kitty. Do not install kitty with Nix, because it won’t work - here’s why.
<SNIP>
<SNIP>
<SNIP>
<SNIP>
Installing packages
Now you have two options. If you don’t care about reproducibility and being able to configure everything in one file and replicate your environment across different machines, then you can just install packages like in any other package manager. See my other guide to actually install software.
The difference will be:
- Install the package inside
nix-template:
Shut down your
nix-template(TemplateVM) to save the state of your template.Only after that, turn on
nix-app(AppVM) to inherit that template. If you are using home-manager, you run it again innix-appto get the changes in~/.nix-profileto actually use those packages because your/homefolder is persistent and not cloned from TemplateVM.
After installing or updating packages in your TemplateVM, shut it down fully before launching your AppVM
Setting up home-manager in TemplateVM
Download the configs at GitHub.
To use your home-manager config, place it inside nix-template in the /nix/home-manager folder.
Here I’ve created a home-manager-build.sh script to make installation steps that are impossible to make declaratively.
The trick in setting the home-manager folder inside /nix is that this folder will also be cloned to your nix-app, so all you need to do to start using your config is:
- Start
home-manager-build.shinsidenix-template
(to install the packages in /nix)
Shut down
nix-templateTurn on
nix-appStart
home-manager-build.shinsidenix-app
(to get links to the packages in ~/.nix-profile)
Restart the terminal
If you don’t have the commands, fix PATH:
export PATH="/nix/var/nix/profiles/default/bin:$HOME/.nix-profile/bin:$PATH"
For managing apt packages, for example, packages whose Nix versions are not running properly on Qubes, edit the home-manager-build.sh file. For adding new Nix packages, managing config files, etc., edit home.nix instead. This way your setup can be declarative enough for it to be very portable. Don’t forget to use Git to track changes each time you make a noticeable change in any of the configurations, so you can roll back later if anything goes wrong. For testing changes, you can edit the same configs in the AppVM and apply them with home-manager-build.sh. Because it’s an AppVM, these changes will be wiped at reboot.