Getting Started
Quick Start
Get a microVM running in under 5 minutes.
1. Run an OCI Image
Section titled “1. Run an OCI Image”The shortest current path is a one-shot microVM from an OCI image:
mvmctl machine run --image alpine -- uname -aThis pulls or reuses the cached image, records OCI provenance, boots a transient microVM, runs the command, and tears the VM down. You do not need host Nix for this path.
Use this when you want “run this command in a fresh microVM.” Use the flake and manifest flows below when you are building a custom image or a repeatable project environment.
For a scenario-led map of when to use each machine workflow, read Machine use cases. Before depending on a backend capability, read Machine limitations.
For a named machine that survives across starts:
# Create the spec, then start itmvmctl machine create alpine-dev --image alpinemvmctl machine start alpine-dev
# Or create and start in one commandmvmctl machine start alpine-dev --image alpine
mvmctl machine exec alpine-dev -- uname -amvmctl machine stop alpine-dev2. Prepare the Builder VM (optional)
Section titled “2. Prepare the Builder VM (optional)”mvmctl bootstrapnix build for a --flake source runs inside a headless builder
VM — a build engine, not something you get a shell into. It
auto-bootstraps the first time you run mvmctl machine build or
mvmctl machine run --flake ...; mvmctl bootstrap pre-fetches it
ahead of time so that first build isn’t slowed by a cold-start fetch.
Builds run in a builder microVM that mvm sets up automatically — you
don’t need Nix on your host. The builder owns its own /nix/store
and keeps it warm across builds. Where the builder VM runs depends on
your platform:
- Linux with
/dev/kvm: auto-selects the QEMU builder backend; your built workloads boot on Firecracker. - macOS 26+ Apple Silicon: auto-selects the HVF builder backend (Hypervisor.framework, vsock-only, no Homebrew deps), with an automatic fallback to libkrun if HVF fails to create its VM.
- macOS 13–25 Apple Silicon: auto-selects the libkrun builder
backend (the in-process VMM from the
slp/krunHomebrew trio).
mvm targets Apple Silicon on macOS and /dev/kvm on Linux. There is no Docker
or container runtime path; a host without a supported microVM backend surfaces a
backend-unavailable error rather than silently degrading.
mvmctl doctor reports the resolved builder backend and flags any missing
host dependencies. For an interactive shell, boot a workload instead — see
Interactive Console below.
3. Day-to-Day Commands
Section titled “3. Day-to-Day Commands”mvmctl machine ls # List every microVM (alias: ps)mvmctl machine stop --all # Stop all running VMsmvmctl doctor # Check system dependencies and configurationmvmctl machine console vm # Interactive shell into a running VM (PTY-over-vsock)4. Build and Run
Section titled “4. Build and Run”Build a microVM image and run it in one command:
mvmctl machine run --flake . --cpus 2 --memory 1024Run persistently with signed ingress:
mvmctl machine run --flake . --name my-vm --port 8080:8080Or build separately:
mvmctl machine build --flake . --profile minimalmvmctl machine run --flake .5. Manifests
Section titled “5. Manifests”A manifest is the project-local build contract. It sits next to flake.nix
and records the flake target plus runtime sizing:
mvmctl init base-worker --preset workercd base-worker$EDITOR mvm.tomlmvmctl machine buildmvmctl machine run --manifest .Use mvmctl manifest ls and mvmctl manifest info to inspect built
manifest slots. See Manifests for the full flow.
Image-backed manifests can also define a durable machine spec:
image = "alpine:3.20"cpus = 2mem = "512M"mvmctl machine create alpine-dev --manifest ./mvm.toml6. Image Catalog
Section titled “6. Image Catalog”Browse the bundled catalog and scaffold from a curated entry:
mvmctl catalog list # Browse available entriesmvmctl init my-app --catalog minimal # Scaffold from a catalog entrymvmctl machine build my-app # Build the manifestmvmctl machine run --manifest my-app # Boot the VM7. Interactive Console
Section titled “7. Interactive Console”Access a running VM without SSH — uses PTY-over-vsock:
mvmctl machine console myvm # Interactive shellmvmctl machine console myvm --command "ls -la" # One-shot command8. Sandboxed One-Shot Commands
Section titled “8. Sandboxed One-Shot Commands”mvmctl machine run -- <cmd> boots a fresh transient microVM, runs a single
command, and tears it down on exit — like docker run --rm, but with a
Firecracker microVM as the sandbox. Name a source with --image, --flake,
or --manifest.
mvmctl machine run --image alpine -- uname -a # OCI image, one-shotmvmctl machine run --flake . --mount .:/work -- ls /work # share host dir, read-onlymvmctl machine run --image alpine -e DEBUG=1 -- env | grep DEBUG # inject env varsmvmctl machine run --manifest my-tpl -- /bin/true # registered templateWhen you reuse a registered template that has a captured snapshot, exec restores the captured state instead of re-provisioning from scratch, so repeat runs skip the first-run setup cost. See the Sandboxed Exec guide for details.
9. Named Networks
Section titled “9. Named Networks”Create isolated networks for different projects:
mvmctl network create myprojectmvmctl machine run --flake .mvmctl network list10. Diagnostics & Security
Section titled “10. Diagnostics & Security”mvmctl doctor # Deps, available backends, and security posture (one report)mvmctl machine logs vm1 # View guest console logsmvmctl cache info # Cache directory disk usageNext Steps
Section titled “Next Steps”- Your First MicroVM — write a Nix flake and boot it
- Sandboxed Exec — run a single command in a fresh microVM
- Machine use cases — choose the right machine workflow
- Machine limitations — explicit backend and feature limits
- CLI Commands — full command reference
- Manifests — reusable base images via
mvm.toml - Troubleshooting — common issues