vmlab

Alpha software (v0.1.0) — vmlab is under active development.

Expect frequent breaking changes to labs, templates, and the CLI.

Declarative VM labs · QEMU/KVM

Orchestrate virtual machine labs from your terminal.

vmlab turns a single vmlab.wcl into a running fleet of machines — VMs, containers, networks and provisioning, wired automatically. Boot, snapshot, and tear down complex topologies with one command.

Open source · MIT · Linux, or Windows 11 via WSL 2

vmlab.wclwcl
import <vmlab.wcl>

lab "demo" {

  segment "lan" {
    subnet = "10.81.0.0/24"
    nat    = true                                  // guest egress
    forward { host_port = 12222 to = "alp:22" }    // host SSH → guest
  }

  vm "alp" {
    template = "ghcr.io/vmlabdev/vmlab-templates/alpine-3.23"
    arch     = "x86_64"                            // multi-arch ref: pick one
    memory   = 1GiB
    nic { segment = "lan" }

    provision "scripts/setup.ws" { }   // wscript, typed & checked
  }

  container "web" {                    // an OCI image, run as a micro-VM
    image   = "nginx:1.27"
    profile = "container"         // micro-VM hardware floor
    nic { segment = "lan" }
  }
}

A taste

From a single file to a running lab in one command.

The lab is the file: segments with built-in DHCP, DNS and NAT, VMs booting linked clones of a template — pulled from an OCI registry on first up if it isn't local — and OCI containers running as micro-VMs on the same wire. vmlab validate type-checks the whole lab (wscript included) before anything boots.

Capabilities

Everything a lab needs, in one binary.

No bridges, no root, no setup step — a per-user daemon pair starts on demand and the whole network fabric runs in userspace.

Declarative labs

A lab {} block declares VMs and the networks between them. Hardware comes from guest OS profiles with clear precedence, so most VMs are a couple of lines — vmlab validate checks it all before boot.

Powered by QEMU/KVM

Runs x86_64, aarch64, and riscv64 guests from the same tool — KVM-accelerated natively, emulated across arches. No KVM? It falls back to TCG with a loud warning.

Userspace networking

Per-lab virtual switches with DHCP, DNS, NAT, routes, port forwards and L3 filtering — all declared in the lab, no taps, no CAP_NET_ADMIN, no manual wiring.

Snapshots

Capture a single VM or the whole lab, then roll back to any snapshot in seconds.

Guests without networking

vmlab's own guest agent rides a virtio-serial port, so exec, file copy, shells and readiness never touch the guest's network — automation works before the guest is even configured, and in both VMs and containers.

OCI distribution

Push templates to any OCI registry as chunked, multi-arch artifacts; reference a registry ref straight from a lab and vmlab up pulls it on demand.

GUI automation & vision

Keystrokes, mouse, screenshots, image matching and OCR — script installers and GUI flows headlessly, even where no agent can run.

wscript provisioning

Provision scripts and event handlers drive guests through a typed API, compiled and type-checked at validate time — handle sysprep, wait for ready, gate the next step on it.

Linked-clone templates

Build a sealed qcow2 template once from installer media; labs boot copy-on-write clones, so templates stay immutable and labs stay small on disk.

Containers as lab machines

A container {} block runs an OCI image in its own micro-VM: same segments, same DNS, same snapshots and the same agent as a VM — a real kernel boundary, not a namespace.

Playbook convergence

Declare config-weave playbooks inside the machine they converge. vmlab up applies them, reboots when a step demands it, and vmlab playbook check reports drift without changing anything.

Reference

The manual

The complete vmlab manual — every block, verb and API, cross-linked and searchable.

vmlab

The complete vmlab manual — a guide to labs, templates, networking and dev machines, hands-on tutorials, and the full reference for every block, verb and wscript API.

Read the manual

Getting started

Install it and boot your first lab.

Needs /dev/kvm (on WSL 2 enable nested virtualisation). The manual's Getting started part walks through each step.

  1. Install the CLI

    curl -fsSL https://vmlab.io/install.sh | sh

  2. Write a lab, then validate it

    vmlab validate

  3. Boot it

    vmlab up