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 quite 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 and prayers.
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.
UPDATE (2025-06-10): 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-app
to get the changes in~/.nix-profile
to actually use those packages because your/home
folder 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.sh
insidenix-template
(to install the packages in /nix
)
Shut down
nix-template
Turn on
nix-app
Start
home-manager-build.sh
insidenix-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.