infrastructure-as-code

NixVM: reliable, declarative virtualisation with Nix

NixVM is a virtualisation approach built on the Nix package manager, enabling declarative, version-controlled VM definitions that can be reproduced, tested, and rolled back reli...

Mara Ellison
NixVM: reliable, declarative virtualisation with Nix

What is NixVM and why it matters for reproducible infrastructure

NixVM is a virtualisation approach built on the Nix package manager, enabling declarative, version-controlled VM definitions that can be reproduced, tested, and rolled back reliably. Unlike imperative VM workflows where changes accumulate over time, NixVM treats infrastructure as code and ensures that identical configurations produce identical environments across development, CI, and production. This matters for teams that need strong reproducibility, safe experiments, and auditable infrastructure changes without sacrificing isolation or performance.

Core concepts and architecture

NixVM is not a standalone hypervisor but a set of patterns and tooling that leverages Nix’s declarative model to manage virtual machines. It combines Nix expressions, flakes, and the Nix registry with lightweight VMs to deliver deterministic builds and configurations. By using atomic rollbacks and content-addressable storage, NixVM makes it possible to switch between infrastructure versions instantly and to recover from failed changes safely. These properties align VM lifecycle management with the same reliability guarantees Nix provides for software packages and system configurations.

Declarative specifications

With NixVM, you define VMs in declarative Nix expressions that describe packages, users, services, and network settings. This makes it straightforward to version control configurations, share them across teams, and generate environments from a single source of truth. Because derivations are content addressed, small changes in configuration produce distinct builds, reducing the risk of configuration drift and unintended side effects.

Atomic rollbacks and checkpoints

NixVM supports atomic rollbacks so you can revert a VM to any previously known good state without manual snapshots or fragile scripts. Checkpoints are created whenever a new configuration is applied, giving you a reliable undo path for experiments, updates, or security patches. In combination with Nix’s garbage collector, old generations are retained until explicitly removed, providing both safety and storage efficiency.

Typical workflows and tooling

Effective NixVM usage depends on consistent tooling and workflow choices. Below is a streamlined overview of common steps teams take when working with NixVM-driven environments.

Stages in a NixVM lifecycle

  • Define: Author Nix expressions that describe the intended VM, including OS image, packages, users, and firewall rules.
  • Build: Use nix-build or flakes to instantiate the configuration and produce a VM derivation.
  • Deploy: Start or import the VM in your chosen hypervisor (QEMU, VirtualBox, or container-based lightweight VMs) via NixVM tooling.
  • Test: Run integration and property-based tests against the deployed VM, leveraging the same derivation used in production.
  • Rollout: Promote verified configurations across stages, relying on identical artefacts from build to production.
  • Rollback: If an issue appears, switch to a prior generation with minimal coordination and no manual image surgery.

Comparative overview: NixVM vs traditional VM management

Understanding how NixVM differs from conventional VM workflows clarifies where it adds value and what tradeoffs apply. The table below highlights key attributes and expected outcomes for each approach.

Attribute NixVM Traditional imperative VM management
Configuration model Declarative Nix expressions with content-addressable builds Manual steps, scripts, or ad-hoc GUI actions
Reproducibility High: identical configurations are deterministically rebuilt Low to moderate: drift and manual changes are common
Rollback mechanism Atomic rollbacks to prior Nix generations Snapshot-based; relies on external tooling and discipline
Change auditing Git-tracked expressions and derivations Log files or isolated change records, often incomplete
Testing integration Direct use of the same derivation in test and prod Often divergent environments, increasing ‘works on my machine’ risk

Practical considerations and limits

While NixVM offers strong guarantees, teams should weigh operational realities and constraints. Performance is usually close to native because the VM runs on mainstream hypervisors, but layer translation and Nix evaluation add modest overhead. Learning curve is real: teams must become comfortable with Nix expressions, flakes, and tooling to get full value. NixVM also assumes some familiarity with virtualisation concepts such as bridging, storage pools, and secure boot, especially in automated pipelines.

Integration with broader Nix ecosystems

NixVM works well within larger Nix-based workflows, including NixOS, devenv, and CI pipelines. By sharing the same Nix repository across applications, services, and infrastructure, you reduce context switches and increase confidence that what you test locally behaves identically in staging and production. Integration points include flake inputs for VM definitions, shared nixpkgs versions, and consistent secrets management patterns that avoid duplicating credentials across environments.

Security, compliance, and auditability

Because every VM configuration is expressed as code and stored in a content-addressable store, audits become straightforward: you can inspect exact derivations, diff versions in Git, and verify that running instances match approved definitions. NixVM facilitates least-privilege setups by encoding users, firewall rules, and service permissions in declarative specs that are reviewed and tested like application code. These traits align well with compliance practices that demand traceable, repeatable infrastructure changes and strong separation between environments.

Getting started with NixVM

To try NixVM, start by defining a simple VM in a Nix flake, specifying the hypervisor and desired packages. Use nix develop or nix-shell to iterate quickly, and commit expressions to a Git repository to track changes. Run tests against the built VM derivation before promoting to shared environments. Gradually introduce rollbacks, integrate with CI, and document workflows so new team members can understand and safely modify VM definitions without breaking production.

Key takeaways

  • NixVM treats virtual machines as code, using declarative Nix expressions for consistent, reproducible environments.
  • Atomic rollbacks and checkpoints give you safe, instant undo across development, testing, and production.
  • Identical derivations reduce drift and make it easier to audit, test, and promote infrastructure changes.
  • Expect a learning curve and modest tooling overhead, but strong payoffs in reliability and confidence.