Jump to content

Nixos-shell: Difference between revisions

From Official NixOS Wiki
Onny (talk | contribs)
Graphical session: Simplify config
Onny (talk | contribs)
Graphical session: Enable auto screen resize
 
(One intermediate revision by the same user not shown)
Line 58: Line 58:
   };
   };
};
};
</nowiki>|name=|lang=nix}}If you want clipboard-sharing to work between host and guest, you need to install virt-viewer on your host.{{file|3=<nowiki>
</nowiki>|name=|lang=nix}}If you want auto screen resize support and clipboard-sharing between host and guest to work, append the following lines to your guest config.{{file|3=<nowiki>
{ ... }: {
  environment.systemPackages = [ pkgs.virt-viewer ];
};
</nowiki>|name=/etc/nixos/configuration.nix|lang=nix}}Append the following lines to your guest config.{{file|3=<nowiki>
{ ... }: {
{ ... }: {
   [...]
   [...]
  nixpkgs.overlays = [
    (final: prev: {
      qemu = prev.qemu.overrideAttrs (old: {
        configureFlags = old.configureFlags ++ ["--enable-gtk-clipboard"];
      });
      qemu_kvm = prev.qemu_kvm.overrideAttrs (old: {
        configureFlags = old.configureFlags ++ ["--enable-gtk-clipboard"];
      });
    })
  ];


   virtualisation.qemu.options = [
   virtualisation.qemu.options = [
     "-display" "spice-app"
     "-device virtio-vga-gl"
     "-device" "virtio-serial-pci"
     "-display gtk,gl=on"
     "-chardev" "spicevmc,id=vdagent,name=vdagent"
     "-chardev qemu-vdagent,id=vdagent,name=vdagent,clipboard=on"
     "-device" "virtserialport,chardev=vdagent,name=com.redhat.spice.0"
     "-device virtio-serial"
    "-device virtserialport,chardev=vdagent,name=com.redhat.spice.0"
   ];
   ];


Line 90: Line 98:
};
};
</nowiki>|name=|lang=nix}}
</nowiki>|name=|lang=nix}}
=== Mounting host directories ===
=== Mounting host directories ===



Latest revision as of 05:43, 18 June 2026

nixos-shell is a small helper script for spawning lightweight NixOS virtual machines in a shell.

Installation

Add following line to your system configuration to install the program

environment.systemPackages = [ pkgs.nixos-shell ];

Usage

Simple port forward

Create a single example file containing the system configuration for the virtual machine

❄︎ myvm.nix
{ pkgs, ... }: {
  services.dokuwiki.sites."localhost" = {
    enable = true;
    settings.title = "My Wiki";
  };
}

In this example, we'll have a virtual guest machine running an instance of DokuWiki on port 80. Start the VM while forwarding port 8080 on the host to port 80 on the guest

QEMU_NET_OPTS="hostfwd=tcp::8080-:80" nixos-shell myvm.nix

After the VM is successfully booted, DokuWiki will be available on http://localhost:8080

Reference local nixpkgs folder

Using the -I nixpkgs parameter, you could choose to use a local nixpkgs repository, for example to test unfinished packages or modules:

nixos-shell -I nixpkgs=/home/myuser/projects/nixpkgs myvm.nix

Graphical session

Following snippet will spawn a QEMU session with a graphical screen running GNOME, configured to auto login the user nixos.

❄︎ 
{ ... }: {
  virtualisation.memorySize = 8096;
  virtualisation.cores = 8;

  virtualisation.graphics = true;

  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  services.displayManager.autoLogin = {
    enable = true;
    user = "nixos";
  };

  users.users.nixos = {
    isNormalUser = true;
    initialPassword = "nixos";
  };
};

If you want auto screen resize support and clipboard-sharing between host and guest to work, append the following lines to your guest config.

❄︎ 
{ ... }: {
  [...]

  nixpkgs.overlays = [
    (final: prev: {
      qemu = prev.qemu.overrideAttrs (old: {
        configureFlags = old.configureFlags ++ ["--enable-gtk-clipboard"];
      });
      qemu_kvm = prev.qemu_kvm.overrideAttrs (old: {
        configureFlags = old.configureFlags ++ ["--enable-gtk-clipboard"];
      });
    })
  ];

  virtualisation.qemu.options = [
    "-device virtio-vga-gl"
    "-display gtk,gl=on"
    "-chardev qemu-vdagent,id=vdagent,name=vdagent,clipboard=on"
    "-device virtio-serial"
    "-device virtserialport,chardev=vdagent,name=com.redhat.spice.0"
  ];

  services.spice-vdagentd.enable = true;

  systemd.user.services.spice-vdagent = {
    description = "spice-vdagent user daemon";
    after = [ "spice-vdagentd.service" "graphical-session.target" ];
    requires = [ "graphical-session.target" ];
    wantedBy = [ "graphical-session.target" ];
    serviceConfig = {
      ExecStart = "${pkgs.spice-vdagent}/bin/spice-vdagent -x";
    };
    unitConfig = {
      ConditionPathExists = "/run/spice-vdagentd/spice-vdagent-sock";
    };
  };

};

Mounting host directories

This snippet mounts the directory calendar which resides in the working directory where you run nixos-shell on the host. It gets mounted to /var/lib/nextcloud/store-apps/calendar on the guest. The target directory must exist before mounting gets executed.

≡︎ 
{ ... }: {
  nixos-shell.mounts.extraMounts = {
    "/var/lib/nextcloud/store-apps/calendar" = {
       target = ./calendar;
       cache = "none";
    };
  };
};

Mounting is done through the network filesystem protocol 9p. Currently it's not possible to mount the target directory with a specific UID/GID, so you'll have to change the permissions on the host directory according to your needs.

Inside Nix Flake

Using following Flakes example, you can start a virtual machine using nixos-shell by just typing nix run

❄︎ flake.nix
{
  description = "Spawns lightweight nixos vm in a shell";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-23.11";
    nixos-shell.url = "github:Mic92/nixos-shell";
  };

  outputs = { self, nixpkgs, nixos-shell }: let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
    start =
      pkgs.writeShellScriptBin "start" ''
        set -e
        export QEMU_NET_OPTS="hostfwd=tcp::8080-:80"
        ${pkgs.nixos-shell}/bin/nixos-shell --flake .
      '';
  in {

    nixosConfigurations.vm = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        (import ./myvm.nix)
        nixos-shell.nixosModules.nixos-shell
      ];
    };

    packages = { inherit start; };
    defaultPackage.x86_64-linux = start;

  };
}

The configuration of the virtual machine is inside the file myvm.nix in the same directory. The virtual machine will use the nixpkgs source defined in the flake inputs.