Skip to content

Install mvm on Linux

Linux is mvm’s Tier 1 target. The full security posture (verified boot, jailer, seccomp tier “strict”) and the project’s tightest boot-time budget (≤ 200ms cold on Firecracker; ≤ 30ms snapshot-cloned) hold here. Other platforms get the same API surface via ADR-013, but Linux is where mvm runs at full pace.

For the full host/backend matrix, see Platform support.

You’ll need:

  • A CPU + kernel with KVM enabled. Most modern x86_64 / aarch64 hosts qualify; verify with:

    Terminal window
    test -w /dev/kvm && echo "KVM accessible" || echo "KVM not accessible"

    If /dev/kvm exists but is root-only, add yourself to the kvm group: sudo usermod -aG kvm "$USER" (re-login required).

  • Rust 1.85+ if you build mvmctl from source.

You do not need Nix on your host. You run mvmctl build from the host, and mvm runs Nix evaluation and nix build through the project builder VM before extracting the resulting rootfs back to your host. See Builder VM for the design.

Terminal window
curl -fsSL https://raw.githubusercontent.com/tinylabscom/mvm/main/install.sh | sh
Terminal window
MVM_VERSION=v0.13.0 curl -fsSL https://raw.githubusercontent.com/tinylabscom/mvm/main/install.sh | sh
Terminal window
git clone https://github.com/tinylabscom/mvm.git
cd mvm
cargo build --release
install -m 0755 target/release/mvmctl ~/.local/bin/mvmctl
Terminal window
cargo install mvmctl
Terminal window
mvmctl doctor

doctor checks for /dev/kvm access, the cache directory permissions, and the active backend. On a healthy Linux + KVM host you’ll see Firecracker selected as the auto-default. Host-side Nix is reported but not required.

Terminal window
mkdir my-app && cd my-app
mvmctl init
mvmctl run

mvmctl init scaffolds an mvm.toml + flake.nix in your project. mvmctl run reads mvm.toml, builds the rootfs via Nix (using your flake’s mvm.lib.x86_64-linux.mkGuest call), and boots it on Firecracker. Expected cold boot: ≤ 200ms.

See Building MicroVM Images for the user-facing flake API.

/dev/kvm: permission denied” — your user isn’t in the kvm group. sudo usermod -aG kvm "$USER" and start a new shell.

mvmctl run falls back to libkrun even though I have KVM” — check mvmctl doctor output. The auto-select ladder picks Firecracker only when /dev/kvm is writable; if it’s root-only, libkrun wins as the cross-platform fallback. Same fix as above.

Nix build is slow — first builds pull from cache.nixos.org and cache.flakehub.com. Subsequent builds hit the builder VM’s /nix/store, which mvm keeps warm across runs.

Firecracker errors with “TooManyOpenFiles” — bump the open-files ulimit: ulimit -n 4096. mvm sets a sensible default but very-high-density runs need headroom.

mvm doesn’t need Nix on the host — the builder VM handles mvm image builds. You may still want host-side Nix if you’re:

  • contributing to mvm itself and want a shared /nix/store between your editor’s build commands and mvm’s,
  • already running a nix-daemon for other projects.

If you opt in, Determinate Nix is the easiest path:

Terminal window
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

The upstream NixOS installer also works:

Terminal window
sh <(curl -L https://nixos.org/nix/install) --daemon

Installing host-side Nix does not change the normal mvmctl build contract: the CLI remains the host control plane, and the builder VM remains the image build boundary.

  • Ubuntu/Debianapt install qemu-utils e2fsprogs if you need mkfs.ext4 for the smoke test.
  • Fedora/RHELdnf install e2fsprogs qemu-img. Make sure SELinux isn’t blocking /dev/kvm access (it usually isn’t, but audit2why is your friend if it does).
  • Archpacman -S e2fsprogs qemu-img. Already lean.
  • NixOS — easiest path: nix profile install github:tinylabscom/mvm. KVM is enabled by default; kvm group membership is the only thing to verify.