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. running qubes template manager

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.

qubes template manager

Then create a TemplateVM qube that clones the TemplateVM you copied. From now on, I will refer to that VM as nix-template. create new qube creating nix-template TemplateVM Then create an AppVM that will use nix-template as its base. creating nix-app AppVM

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

sudo vi /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
Acquire::http::Proxy "http://127.0.0.1:8082/";
Acquire::tor::proxy "http://127.0.0.1:8082/";

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:

sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon

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.

user@nix-template:~$ sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon
<SNIP>
Switching to the Multi-user Installer
Welcome to the Multi-User Nix Installation
<SNIP>

Would you like to see a more detailed list of what I will do?
[y/n] n

<SNIP>

Can I use sudo?
[y/n] y

Yay! Thanks! Let's get going!

<SNIP>

Alright! We're done!
Try it! Open a new terminal, and type:

  $ nix-shell -p nix-info --run "nix-info -m"

<SNIP>

---- Reminders -----------------------------------------------------------------

Nix won't work in active shell sessions until you restart them.

Press enter/return to acknowledge.

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:

  1. Install the package inside nix-template:
user@nix-template:~$ nix-env -iA nixpkgs.neovim
installing 'neovim-0.11.2'
  1. Shut down your nix-template (TemplateVM) to save the state of your template.

  2. Only after that, turn on nix-app (AppVM) to inherit that template. If you are using home-manager, you run it again in nix-app to get the changes in ~/.nix-profile to actually use those packages because your /home folder is persistent and not cloned from TemplateVM.

TIP

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.

user@nix-template /nix/home-manager $ ls
flake.lock  flake.nix  home-manager-build.sh  home.nix

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:

  1. Start home-manager-build.sh inside nix-template

(to install the packages in /nix)

  1. Shut down nix-template

  2. Turn on nix-app

  3. Start home-manager-build.sh inside nix-app

(to get links to the packages in ~/.nix-profile)

  1. Restart the terminal

  2. 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.