The purpose of this module is to deploy an entire NixOS based server, host and virtual machines, declaratively.
"It's turtles all the way down"
This is currently an opinionated module: it permits creating NixOS containers or VMs only, for a good reason: the interface expects that you will pass in arbitrary nixosConfigurations to apply to the virtual systems you are spinning-up.
Skip to the example configuration to see how you can create virtual machine profiles declaratively.
The module handles bootstrapping the host environment and evaluating the configuration.
A bare minimal NixOS host with flakes enabled should be enough to start from, however...
! You will need at least one generation already running Incus !
Here is an example configuration.nix you can import to build the bare minimal NixOS with Incus.
Provide a value for your_name.
{ config, lib, pkgs, inputs, self, ... }:
{
virtualisation.incus.enable = true;
networking.nftables.enable = true;
users.users.your_name.isNormalUser = true;
users.users.your_name.extraGroups = [ "incus-admin" ];
}run sudo nixos-rebuild switch. Once the rebuild completes, run Incus init:
incus admin initThat is the required pre-requisite to ensure storage and networking is set up with defaults.
#example flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Track the github repository
incus-nixos.url = "github:NWoodsman/Incus-NixOS";
};
outputs = { self, nixpkgs, incus-nixos, ... }: {
nixosConfigurations.my-host-machine = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hardware-configuration.nix
./configuration.nix
# add the Incus-NixOS module
incus-nixos.nixosModules.default
];
};
};
}Inside your configuration file, set up some virtual machines:
{ pkgs, ... }: {
# 1. Base Virtualization & Networking Requirements for the Host
virtualisation.incus.enable = true;
networking.nftables.enable = true; # Incus needs nftables to manage native bridge networks
users.users.your_name.isNormalUser = true;
users.users.your_name.extraGroups = [ "incus-admin" ];
# 2. Declarative Incus-NixOS Flake Configuration
services.incus-nixos = {
enable = true;
# Track standard tracking imagery across deployments
# This is the Incus NixOS image that will be used to spool up the child VMs/containers
image = "images:nixos/unstable";
instances = {
# Example 1: A lightweight system container utilizing standard defaults
"production-api-container" = {
type = "container";
ipv4Address = "10.50.0.40"; # Binds static maps to host & inner NIC paths
nixosConfiguration = { pkgs, ... }: {
# NetworkManager.enable = true is injected by the module automatically
environment.systemPackages = [ pkgs.curl pkgs.git ];
services.nginx.enable = true;
};
};
# Example 2: A full hardware Virtual Machine using our automated cloud-init bootstrap pipeline
"isolated-database-vm" = {
type = "virtual-machine";
ipv4Address = "10.50.0.50"; # Crucial: VMs require a static IP for the initial SSH transport sync
config = {
"limits.cpu" = "4";
"limits.memory" = "4GiB";
};
nixosConfiguration = { pkgs, ... }: {
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
};
};
};
};
};
}