How can I run an image from nixos-anywhere in an emulator like VirtualBox?

I’m trying to get into setting up multiple hosts with NixOS and I figured I’d start with nixos-anywhere, cause I found a straightforward tutorial, but can I somehow also get an image that I can load into something like VirtualBox?

My first target is building a flake for an rpi with kodi, so I’d like to check that it’s working as expected in an emulator before I push it to the rpi.

Does nixos-anywhere support something like that?:wink:

I don’t think nixos-anywhere supports this specifically. You could set up a virtual machine with ssh keys and use it as a target for nixos-anywhere (you might need to do some configuration in VirtualBox in order to access the guest from the host). For testing a configuration, you can also use nixos-generators or the build-vm subcommand of nixos-rebuild (both of which are a lot less effort than manually setting up a VM).

No, disko does support it in the attribute of the system configuration. It is implemented as a VM configuration that runs some self-checks on startup. All you have to do is to nix-build that attribute of your evaluated configuration, for example like this:


This is a working sample to give you more than just the idea, but please apply Nix language best practices in reality.

# default.nix
  pkgs = import <nixpkgs> { };
  disko = builtins.fetchTarball "";
  # convenience wrapper to evaluate a configuration
  nixos = config: pkgs.nixos [ "${disko}/module.nix" config ];
  # a sample system configuration
  machine-config = { ... }: {
    boot.loader.systemd-boot.enable = true;
    disko.devices.disk.main = {
      device = "/dev/sda";
      content = {
        type = "gpt";
        partitions = {
          boot = {
            size = "1G";
            type = "EF00";
            content = {
              type = "filesystem";
              format = "vfat";
              mountpoint = "/boot";
          root = {
            content = {
              type = "filesystem";
              format = "ext4";
              mountpoint = "/";
    system.stateVersion = "23.11";
  # evaluated machine configuration
  machine = nixos machine-config;
  tests =;

To run the test:

nix-build -A tests --no-out-link

(Without --no-out-link it will produce an empty result symlink in the current directory, because the derivation, which runs the test when it’s built, doesn’t write anything to the store.)

What I also played around with recently is having two helper scripts in the development shell to further ease testing:

# default.nix
  # ...
  run-vm = pkgs.writeShellApplication {
    name = "run-vm";
    text = ''
      # make QEMU create the disk image in memory
      pushd "$(mktemp -d)" > /dev/null
      "$(nix-build ${toString ./.} -A --no-out-link)"/bin/run-nixos-vm "$@"
      # clean up
      rm nixos.qcow2
      popd > /dev/null
  run-tests = pkgs.writeShellApplication {
    name = "run-tests";
    text = ''
      nix-build ${toString ./.} -A tests --no-out-link "$@"
  # ...
  inherit machine;
  shell = pkgs.mkShell {
    packages = [ run-vm run-tests ];

Add a shell.nix for convenience, since now default.nix contains more than one derivation and otherwise you’d have to run nix-shell -A shell every time. Then you can run the configuration in a VM with run-vm, and run the tests with run-tests within your nix-shell.

Expanding the test suite to multiple machine configurations is left as an exercise for the reader.

1 Like

I’m on deep water, here, but at least I tried;)

[b0ef@ximian:~/nix-build/tst1]$ nix-build -A shell
these 3 derivations will be built:
this path will be fetched (0.96 MiB download, 5.96 MiB unpacked):
copying path '/nix/store/qc5c375far00lbcmhc55ph1bf0djqb3i-ShellCheck-0.9.0' from ''...
building '/nix/store/05y9s0x8nn8dlfn8fy8dmykkznqzaaci-run-tests.drv'...
building '/nix/store/l0qg5q37kdmikyhlfxmzfvz77jyqykkh-run-vm.drv'...

In /nix/store/a64cvvlf9d4qvspir5srpsb6p17dk507-run-vm/bin/run-vm line 6:
^-----^ SC2034 (warning): machine appears unused. Verify use (or export if used externally).

For more information: -- machine appears unused. Verify us...
error: builder for '/nix/store/l0qg5q37kdmikyhlfxmzfvz77jyqykkh-run-vm.drv' failed with exit code 1;
       last 7 log lines:
       > In /nix/store/a64cvvlf9d4qvspir5srpsb6p17dk507-run-vm/bin/run-vm line 6:
       > machine="$1"
       > ^-----^ SC2034 (warning): machine appears unused. Verify use (or export if used externally).
       > For more information:
       > -- machine appears unused. Verify us...
       For full logs, run 'nix log /nix/store/l0qg5q37kdmikyhlfxmzfvz77jyqykkh-run-vm.drv'.
error: 1 dependencies of derivation '/nix/store/hrvh08g313wbvfr8ia26izq5hd13hxbl-nix-shell.drv' failed to build

Ah yes, that was a remnant of a more involved setup. Edited it out, please try again.

Right, this got built;), but how do I actually run it. Where is the image?;). Sorry, I’m so confused.

If you nix-build (/t) it, it should be as easy as ./result/run-vm.

It’s not a directory here.

[b0ef@ximian:~/nix-build/tst1]$ ./result/run-vm
bash: ./result/run-vm: Not a directory
[b0ef@ximian:~/nix-build/tst1]$ file result
result: symbolic link to /nix/store/35b3p7rxngjl2ny77a32n6kqng356m4k-nix-shell

Start a nix-shell and therein run-vm ?

like nix-shell default.nix, then run-vm inside of that?

If you have a default.nix only then indeed nix-shell -A shell and inside of that run-vm and if you have a separate shell.nix for the shell attribute so to say then just nix-shell and inside of that run-vm.

You’re right;) Quite a step for mankind, or man, me, to figure that one out. Thanks a bunch;)

@573 thanks for the clarification, updated my post a bit so it hopefully is more on first reading.