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.
Disabling tinyproxy
TemplateVMs also have tinyproxy that allows them to install updates through apt
even though they are air-gapped, but when we enable internet access to the whole VM, it would only interfere, so we need to turn it off.
The file you need to configure is /etc/apt/apt.conf.d/01qubes-proxy
### This file is automatically generated by Qubes (/usr/lib/qubes/update-proxy-configs script).
### All modifications here will be lost.
### If you want to override some of these settings, create another file under
### /etc/apt/apt.conf.d.
# Use Qubes Update Proxy
;
;
Here you need to comment out lines starting with “Acquire”:
# Use Qubes Update Proxy
#Acquire::http::Proxy "http://127.0.0.1:8082/";
#Acquire::tor::proxy "http://127.0.0.1:8082/";
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
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"
Download my config here
UPDATE (2025-06-09): As of now, this config is quite old. I’m going to make a configurator that will semi-automatize the process of configuring home-manager for Qubes VMs. Until then, the config I gave above is enough to start using Nix on Qubes.