Nix-Factory is a Nix-based project for building and running NixOS virtual machines. It leverages nixos-generators
to produce QEMU-compatible images, primarily for use with UTM.app on macOS.
I am not happy with any solution for managing Virtual Machines on MacOS. Most of existing tools either focus on GUI, have limited scripting/CLI capabilities or are just weird gimmicks that use custom image format, without NixOS support.
- Build QCOW2 (and other formats supported by
nixos-generators
) VM images via nix flakes. - Manage UTM.app VMs through simple CLI scripts, without need to use GUI at all.
- Preconfigured NixOS user with password and SSH key preinstalled.
- MACHINE
- flake.nix output with a name. They are unique.
- NAME
- Unique identifier for a virtual machine. You can have multiple virtual machines, each with it’s own NAME, but build from the same MACHINE.
Build image based on nixosConfiguration in flake.nix.
./scripts/build-vm.sh <MACHINE>
<MACHINE>
- Name of nixosConfiguration (see flake.nix).
Start a VM based on image built from nixosConfiguration. By default, machine will be named after an image it’s created from. Optionally provide unique name for the VM, so that multiple VMs can be created using the same image.
./scripts/start-vm.sh <MACHINE> [<NAME>]
<MACHINE>
- Name of the nixosConfiguration built using
build-vm.sh
. <NAME>
(optional)- A unique identifier for the VM instance.
./scripts/delete-vm.sh <NAME>
<NAME>
- Name of the VM, matching
<MACHINE>
unless specified during startup.
Remove all UTM machines, built images, and unused Nix store references. Then run the nix garbage collector.
./scripts/cleanup.sh
This rebuilds a live system with nixos-rebuild
command remotely. Note that if the image is freshly built and deployed, first run of this will take some time, due to nix having to rebuild entire system, including nix store (looking for a way to avoid this long wait). Subsequent runs are fast.
This script can also be used to rebuild existing machine based on one flake.nix output into completely different machine, based on different flake.nix output. Sky is the limit.
./scripts/rebuild-host.sh <MACHINE> [<NAME>]
<MACHINE>
- Name of the nixosConfiguration (see flake.nix).
<NAME>
(optional)- A unique identifier for the VM instance.
flake.nix
- Defines the configurations and flake outputs.
common/
- Contains shared configuration, used as nixosModules to avoid unnecessary path traversal.
configurations/
- Contains specialized configurations.
scripts/
- Scripts used to build images and to manage virtual machines.
- [X] Standarize naming in the project (NAME, MACHINE, etc.)
- [X] Find a way to use same nixosConfiguration for building an image, and rebuilding live system