How to use nix-shell in nix VMs (nixos)


I’m relatively new to nixos and I like the ride so far. My usecase may be a bit unusual - I decided to use qemu based appvms ( for most things.

(Why? I deal with malicious code as my day job, so security is very important to me).

Right now I start a VM, do some development/operations, if I’m in the temporary VM and i decide that I need to install for example php, I need to:

  • turn the VM off
  • add php to packages in the VM config file
  • turn the VM on

While what I’d like to do is:

  • nix-shell -p php (it’s already in the shared /nix/ store, so shouldn’t incur any copies?)

I can kinda achieve it with:

nix-channel --add nixpkgs-unstable release nixpkgs-21.11pre326916.7053541084b
nix-channel --update
nix-shell -p php -I nixpkgs=/nix/var/nix/profiles/per-user/user/channels/nixpkgs

but it still unpacks locally to tmpfs, /nix/.rw-store gets 100% full and I’m not able to run even simple packages (like php).

I hope I explained my problem clearly enough :).

TL;DR how to install packages in nixos-built qemu VMs

Perhaps this blog post might be helpful to you?

Thanks for your response! That’s actually almost what I do.

For example, I can build a VM with this command:

nix-build '<nixpkgs/nixos>' -A vm --arg configuration ./example.nix -I ..

But the resulting VMs are not in a state that allows me to install packages:

[user@nixos:~] nix-shell -p vim
error: file 'nixpkgs' was not found in the Nix search path (addit using $NIX_PATH or -I), at (string):1:13

I tried to solve this with the commands I mentioned:

nix-channel --add
nix-channel --update
nix-shell -p vim -I nixpkgs=/nix/var/nix/profiles/per-user/user/channels/nixpkgs

But it still installs to tmpfs instead of using the shared nix store (and fails because there is only 512M available space)

FWIW, I solved this problem in a following way:

Let’s assume I want to run htop on the guest. I open a host console and run:

host$ nix-shell -p htop
<nix-shell>@host$ echo $PATH

and copy the result. Then I do:

guest$ export PATH=[copied path from before]
guest$ htop

in the guest. Because the /nix/ store is shared, everything works correctly (at least as far as I can see).

But if anyone have better ideas, I’ll happily hear them (ability to run nix-shell -p htop in the guest directly would be nice)

I believe this can be automated. See GitHub - Mic92/nixos-shell at 1c44b0600557ed4d34320ad5a2d4f85d267622a7