nixos VM in lxd
Setting up VM images with nixos is incredibly powerful when coupled with declarative nature of nix language itself.
I am using it for running homelab type services and lab type setups. Here is how I have it working for me:
Create the VM
This is a snippet from a shell script I use
name=nixos1
img=nixos/24.05
cpu=4
mem=8
disk=100
incus launch images:$img $name \
--vm \
-c limits.cpu=4 \
-c limits.memory=${mem}GiB \
-c security.secureboot=false \
--device root,size=${disk}GiB
Configure the VM
Assuming you have some nixos configuration, you can upload the config and update the VM.
incus file push ./configuration.nix $name/etc/nixos/configuration.nix
incus exec "$name" -- /run/current-system/sw/bin/bash -i -c "nixos-rebuild switch"
Example Configuration
configuration.nix
{ config, pkgs, lib, modulesPath, ... }:
{
imports =
[
# Include the default lxd configuration.
"${modulesPath}/virtualisation/lxd-virtual-machine.nix"
# Include the container-specific autogenerated configuration.
./lxd.nix
];
boot.supportedFilesystems = [ "nfs" ];
networking = {
hostName = "nixos1"; # Define your hostname.
dhcpcd.enable = false;
useDHCP = false;
useHostResolvConf = false;
};
# For plex...
virtualisation.oci-containers.backend = "docker";
virtualisation.oci-containers.containers = {
plex = {
image = "plexinc/pms-docker";
volumes = [
"/srv/plex/config:/config"
"/srv/plex/tmp:/transcode"
"/data/movies:/data/movies"
"/data/TV:/data/TV"
];
extraOptions = [
"--network=host"
];
environment = {
PLEX_CLAIM = "claim-XXX";
TZ = "America/Los_Angeles";
};
};
};
programs.bash.enableCompletion = true;
services.jellyfin.enable = true;
environment.systemPackages = with pkgs; [
vim
wget
curl
emacs
git
];
services.openssh.enable = true;
networking.firewall.enable = false;
systemd.network = {
enable = true;
networks."50-enp5s0" = {
matchConfig.Name = "enp5s0";
networkConfig = {
DHCP = "ipv4";
IPv6AcceptRA = true;
};
linkConfig.RequiredForOnline = "routable";
};
};
system.stateVersion = "24.05"; # Did you read the comment?
}