Templates
Templates are reusable microVM images built from Nix flakes. Build once, run anywhere. Share via an S3-compatible registry. Template snapshots (--snapshot) are available on the Firecracker backend only — Apple Virtualization, microvm.nix, and Docker do not support snapshots.
Scaffold a Template
Section titled “Scaffold a Template”mvmctl template init my-service --localCreates a minimal directory:
my-service/├── flake.nix # Nix flake via mkGuest├── .gitignore└── README.mdScaffold Presets
Section titled “Scaffold Presets”Use --preset to start from a language-specific template:
mvmctl template init my-api --local --preset python # Python HTTP servicemvmctl template init my-web --local --preset http # HTTP servermvmctl template init my-db --local --preset postgres # PostgreSQLmvmctl template init my-job --local --preset worker # Background workermvmctl template init my-vm --local --preset minimal # Bare minimum (default)From an Existing Flake
Section titled “From an Existing Flake”If you already have a Nix flake, register it directly:
mvmctl template create openclaw --flake ../openclaw --profile minimal --role workermvmctl template build openclawAll flags have defaults: --flake ., --profile default, --role worker, --cpus 2, --mem 1024. Local flake paths are resolved to absolute paths at creation time.
mvmctl template build my-servicemvmctl template build my-service --force # Rebuild even if cachedBuilds run nix build inside the Lima VM to produce kernel + rootfs artifacts. On success, artifact sizes are reported:
Template 'my-service' built successfully (revision: abc123, rootfs: 45.2 MiB, kernel: 12.1 MiB)Snapshots
Section titled “Snapshots”Build with --snapshot to capture a fully booted, healthy VM state. Subsequent runs restore from this snapshot instead of cold-booting — 1-2 second startup instead of minutes.
# Build + snapshot (one-time, waits for all services to be healthy)mvmctl template build my-service --snapshot
# Every subsequent run auto-detects the snapshot and restores instantly:mvmctl up --template my-service --name svcThe snapshot process:
- Builds the template normally (
nix build) - Boots a temporary VM from the built artifacts
- Waits for the guest agent to respond (health check)
- Waits for all integrations to report healthy (e.g., gateway listening)
- Pauses vCPUs and captures a full Firecracker snapshot (
vmstate.bin+mem.bin) - Stores the snapshot alongside the template revision
No flags are needed on run — snapshot detection is automatic. If a template has a snapshot, it’s used; otherwise the VM cold-boots.
Dynamic Configuration with Snapshots
Section titled “Dynamic Configuration with Snapshots”Key insight: Snapshots preserve the OS and application state, but config and secrets drives are created fresh at runtime from your host directories. This means you get instant boots and flexible per-instance configuration.
What’s stored in the snapshot:
- OS and kernel state
- Installed packages and applications
- Memory contents (running services, compiled code caches)
- Network stack configuration
What’s NOT stored (created fresh each run):
- Config drive (
/mnt/config) — built from your--volumeor--config-dir - Secrets drive (
/mnt/secrets) — built from your--volumeor--secrets-dir - Data volumes — built from your
--volume host:guest:size
Multiple Instances from One Snapshot
Section titled “Multiple Instances from One Snapshot”Run production, staging, and dev instances from the same template snapshot with different configurations:
# Production: real API keys, strict configmvmctl up --template my-app --name prod \ -v ./prod/config:/mnt/config \ -v ./prod/secrets:/mnt/secrets
# Staging: test API keys, relaxed configmvmctl up --template my-app --name staging \ -v ./staging/config:/mnt/config \ -v ./staging/secrets:/mnt/secrets
# Dev: no API keys, debug logging enabledmvmctl up --template my-app --name dev \ -v ./dev/config:/mnt/configAll three VMs restore from the same snapshot (1-2 second boot) but get different configs/secrets at runtime. The guest agent automatically remounts config/secrets drives after restore and restarts services with the fresh data.
Benefits:
✅ Instant boots — 1-2 seconds from snapshot instead of minutes cold-booting ✅ Consistent base — all instances run identical OS/app versions ✅ Flexible configuration — each instance gets its own runtime config ✅ No config baked into image — same template works for prod, staging, dev, testing ✅ Easy testing — spin up throwaway instances with test configs in seconds
Share via Registry
Section titled “Share via Registry”Push and pull templates to S3-compatible storage:
mvmctl template push my-servicemvmctl template pull my-servicemvmctl template verify my-service # Verify checksumsConfigure the registry with environment variables:
export MVM_TEMPLATE_REGISTRY_ENDPOINT="https://s3.amazonaws.com"export MVM_TEMPLATE_REGISTRY_BUCKET="mvm-templates"export MVM_TEMPLATE_REGISTRY_ACCESS_KEY_ID="..."export MVM_TEMPLATE_REGISTRY_SECRET_ACCESS_KEY="..."Multiple Roles
Section titled “Multiple Roles”Create templates for multiple roles at once:
mvmctl template create-multi my-app --flake . --roles worker,gatewaymvmctl template build my-app-gatewaymvmctl template build my-app-workerUpdate an existing template’s configuration:
# Increase memory for an existing templatemvmctl template edit openclaw --mem 2048
# Update multiple settings at oncemvmctl template edit my-service --cpus 4 --mem 4096
# Change the flake referencemvmctl template edit my-service --flake /new/pathAfter editing, rebuild the template for changes to take effect:
mvmctl template build my-service --forceAvailable edit options:
--flake- Update the Nix flake reference--profile- Change the flake package variant--role- Update the VM role (worker, gateway)--cpus- Change vCPU count--mem- Update memory in MiB--data-disk- Change data disk size in MiB
Inspect
Section titled “Inspect”template info shows the full picture — spec, current revision, artifact sizes, and snapshot status:
mvmctl template info my-serviceTemplate: my-service Flake: /path/to/flake Profile: minimal Role: worker vCPUs: 2 Memory: 1024 MiB
Current Revision: abc123 Built: 2026-03-14T12:00:00Z Kernel: 12.1 MiB Rootfs: 45.2 MiB Snapshot: present (vmstate: 1.5 MiB, mem: 1024.0 MiB)Use --json for machine-readable output (includes full revision data).
Manage
Section titled “Manage”mvmctl template list # List all templatesmvmctl template info my-service # Show details, sizes, snapshot statusmvmctl template edit my-service --mem 2048 # Edit template settingsmvmctl template delete my-service # Remove a template