Nixos-shell: Difference between revisions
imported>Onny Add example with mounting directories |
m →Graphical session: replace nameless {{file}} template with <syntaxhighlight lang=nix> |
||
| (16 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
[https://github.com/Mic92/nixos-shell | {{DISPLAYTITLE:{{#if:{{NAMESPACE}}|{{NAMESPACE}}:|}}{{lcfirst:{{PAGENAME}}}}}} | ||
[https://github.com/Mic92/nixos-shell nixos-shell] is a small helper script for spawning lightweight NixOS virtual machines in a shell. | |||
== Installation == | == Installation == | ||
| Line 11: | Line 12: | ||
== Usage == | == Usage == | ||
== Simple port forward == | === Simple port forward === | ||
Create a single example file containing the system configuration for the virtual machine | Create a single example file containing the system configuration for the virtual machine | ||
{{file|myvm.nix|nix|<nowiki> | {{file|myvm.nix|nix|<nowiki> | ||
{ pkgs, ... }: { | { pkgs, ... }: { | ||
services.dokuwiki.sites."localhost" = { | services.dokuwiki.sites."localhost" = { | ||
enable = true; | enable = true; | ||
settings.title = "My Wiki"; | settings.title = "My Wiki"; | ||
}; | }; | ||
} | } | ||
</nowiki>}} | </nowiki>}} | ||
| Line 32: | Line 32: | ||
After the VM is successfully booted, DokuWiki will be available on http://localhost:8080 | After the VM is successfully booted, DokuWiki will be available on http://localhost:8080 | ||
== Mounting host directories == | === Reference local nixpkgs folder === | ||
Using the <code>-I nixpkgs</code> parameter, you could choose to use a local ''nixpkgs'' repository, for example to test unfinished packages or modules:<syntaxhighlight lang="console"> | |||
$ nixos-shell -I nixpkgs=/home/myuser/projects/nixpkgs myvm.nix | |||
</syntaxhighlight> | |||
=== Graphical session === | |||
Following snippet will spawn a QEMU session with a graphical screen running GNOME, configured to auto login the user <code>nixos</code>: | |||
<syntaxhighlight lang=nix> | |||
{ ... }: { | |||
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"; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
If you want auto screen resize support and clipboard-sharing between host and guest to work, append the following lines to your guest config: | |||
<syntaxhighlight lang=nix> | |||
{ ... }: { | |||
[...] | |||
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"; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
=== Mounting host directories === | |||
This snippet mounts the directory <code>calendar</code> which resides in the working directory where you run nixos-shell on the host. It gets mounted to <code>/var/lib/nextcloud/store-apps/calendar</code> on the guest. The target directory must exist before mounting gets executed. | This snippet mounts the directory <code>calendar</code> which resides in the working directory where you run nixos-shell on the host. It gets mounted to <code>/var/lib/nextcloud/store-apps/calendar</code> on the guest. The target directory must exist before mounting gets executed. | ||
{{file|myvm.nix|nix|<nowiki> | {{file|myvm.nix|nix|<nowiki> | ||
{ | { ... }: { | ||
nixos-shell.mounts.extraMounts = { | nixos-shell.mounts.extraMounts = { | ||
"/var/lib/nextcloud/store-apps/calendar" = { | "/var/lib/nextcloud/store-apps/calendar" = { | ||
| Line 43: | Line 113: | ||
cache = "none"; | cache = "none"; | ||
}; | }; | ||
}; | |||
}; | }; | ||
</nowiki>}} | </nowiki>}} | ||
Mounting is done through the network filesystem protocol 9p. Currently [https://github.com/Mic92/nixos-shell/issues/71 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. | Mounting is done through the network filesystem protocol 9p. Currently [https://github.com/Mic92/nixos-shell/issues/71 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 <code>nix run</code> | |||
{{file|flake.nix|nix|<nowiki> | |||
{ | |||
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; | |||
}; | |||
} | |||
</nowiki>}} | |||
The configuration of the virtual machine is inside the file <code>myvm.nix</code> in the same directory. The virtual machine will use the nixpkgs source defined in the flake inputs. | |||
[[Category:Container]] | |||
Latest revision as of 19:56, 19 July 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
{ 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
{
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.