Getting started · tutorial
Your first VM
In this tutorial you run a full virtual machine without building anything. The VM's template field names a template published on a public OCI registry, and vmlab up pulls it into your local store the first time. You then open a shell in the guest, attach its console, take a screenshot, and take and restore a snapshot.
Before you start
- vmlab is installed with the runtime tools from Install. No guest assets are needed: the pulled template already carries the agent.
- /dev/kvm is available. The template is x86_64, so it runs under KVM on an x86_64 host.
- Internet access from the host, to pull from ghcr.io. The template is small, and the pull takes a few tens of seconds.
- A VNC viewer for the console step. remote-viewer from virt-viewer is the one vmlab prefers. The step also shows the path with no viewer at all.
Write the lab file
Create a new directory with this vmlab.wcl.
import <vmlab.wcl>
lab "first-vm" {
vm "alp" {
template = "ghcr.io/vmlabdev/vmlab-templates/alpine-3.23"
arch = "x86_64"
memory = 1GiB
nic { nat = true }
}
}
template is an OCI registry reference of the form host/owner/[group/]name[:tag]. With no tag it tracks the moving latest tag, the newest stable version of the published template. :latest-prerelease tracks pre-releases and :<version> pins one. A registry reference always needs arch, because one tag can carry several architectures and vmlab never assumes the host's.
nic { nat = true } is shorthand for attaching the VM to the lab's built-in NAT segment, so you do not have to declare one. The guest gets a DHCP lease and internet egress. memory = 1GiB overrides the size the template recorded; cpus and everything else are inherited from the template and, below it, from its guest OS profile. See Lab file: vm and its children for the whole surface.
Bring it up
up resolves the tag, finds no matching version in the local store, pulls the template, installs it under x86_64/alpine-3.23@<version>, and creates the VM as a linked clone of it. The clone is a qcow2 file whose backing file is the sealed template, so it starts small and the template is never modified. The VM boots and up waits until the guest agent answers, which is what ready means.
A cached version is reused on every later up and never re-pulled implicitly. To fetch a template without starting anything, for instance ahead of a trip, run vmlab pull. To see what the store holds, list it.
The VM is running
vmlab status shows alp running and ready with an address. vmlab template list shows x86_64/alpine-3.23 with the version that was pulled.
Open a shell
vmlab shell attaches an interactive terminal inside the guest over the agent's virtio-serial channel. No SSH and no guest network are involved, so it works even on a VM with no NIC. This VM declares no login {}, so the shell runs as the agent's identity, which is root on Linux.
Inside the guest, confirm where you are, then detach with Ctrl-]. Detaching leaves the VM running.
For a single command, use exec instead. Its exit code becomes the exit code of vmlab exec.
Attach the console
Every VM has a VNC display served on a unix socket whether or not anyone is looking at it. vmlab console attaches a viewer to it. vmlab picks the viewer from your host configuration, else the first of remote-viewer, gvncviewer and vncviewer on your PATH. Closing the viewer window only disconnects. The VM keeps running.
You see the Alpine login prompt on the virtual screen. With no viewer installed, or on WSL 2 where the viewer lives on the Windows side, ask for a TCP bridge instead. vmlab forwards the display to a localhost port and prints the address for you to point any VNC client at.
To open a viewer automatically on every up, set gui = true on the VM or on the lab. The VM still runs headless; the viewer is a separate client process.
Take a screenshot
The same display that the console shows can be captured to a PNG at any moment. This is the basis of screen-driven automation, where a script waits for an image or a piece of text to appear.
Open login.png and you see the same login prompt. With tesseract installed, vmlab vm ocr alp reads the text off the screen instead, and vmlab vm sendkeys alp <chord> types into it. Screens, input and vision covers the whole surface.
You have three doors into the guest
You have run a command over the agent, watched the screen over VNC, and captured it to a file.
Snapshot and restore
A snapshot records a machine's disk, and if the machine is running, its RAM and device state too. Every snapshot remembers the power state it was taken in. Restoring an online snapshot resumes the guest exactly where it was; restoring an offline one leaves it powered off. Write a marker file in the guest, take a snapshot, delete the marker, then restore.
--vm alp narrows the snapshot to one machine. Without it, `snapshot create` captures every VM and container in the lab under one name. Consistency across machines in a lab-wide snapshot is best-effort, not coordinated. Now change the guest and roll it back.
The last command prints before. The VM was running when the snapshot was taken, so it is running again after the restore, with the marker back. Delete the snapshot when you no longer need it.
Snapshots are not a workspace backup
On a dev machine the workspace is re-converged from the host after a restore rather than rolled back with the disk. The source of truth for a workspace is the host directory. See Dev machines and the workspace syncer.
Clean up
destroy deletes the clone and the lab-local state. The pulled template stays in the store, so the next up of any lab that names it starts without a download. To remove it, find its version with `vmlab template list` and remove that reference.
Next steps
- Build a template from an ISO makes your own template from installer media, so any operating system can be a lab machine.
- Distributing templates over registries explains tags, multi-arch indexes, pushing your own templates and searching a registry.
- Snapshots explains online and offline snapshots, what a lab-wide snapshot guarantees, and how snapshots interact with shared folders.
- vmlab vm, vmlab snapshot and vmlab console document the verbs used here.