How to use virtual machines¶
A workshop runs in an LXD container unless its definition says otherwise.
Workshop can instead run it as a full virtual machine
with a kernel of its own,
which draws a harder boundary than a container can.
Reach for a virtual machine when you want that boundary,
or when the workshop itself has to run LXD containers and virtual machines.
The boundary stops at the kernel:
the project directory, including its .git directory,
is still mounted read-write,
and outbound network access is still open,
so a virtual machine doesn’t protect the project
from a coding agent that works in it.
Warning
Prerequisites¶
Before starting, ensure you have these requirements satisfied:
A Workshop installation that supports the
runtimekey.LXD from the
6/candidatechannel, on a host with hardware virtualization available.A workshop you have not launched yet. The runtime is fixed when a workshop is launched, so an already running container workshop cannot be converted.
Check that Workshop lists the runtimes it supports:
$ workshop init --help
...
The supported runtimes are lxd-container (the default) and lxd-vm.
...
Switch LXD to the 6/candidate channel:
$ sudo snap refresh --channel=6/candidate lxd
Warning
Opt in to virtual machines¶
Until you opt in, Workshop refuses to launch a virtual machine workshop and reports the two commands that change that:
$ workshop launch <NAME>
error: cannot launch "<NAME>": runtime "lxd-vm" is experimental
To opt in: "sudo snap set workshop workshop.experimental-vms=1 && sudo snap restart workshop.workshopd"
Run both of them:
$ sudo snap set workshop workshop.experimental-vms=1
$ sudo snap restart workshop.workshopd
Restarted.
Create a virtual machine workshop¶
Generate a definition with the --runtime flag:
$ workshop init <NAME> --runtime lxd-vm
"<NAME>" workshop definition created at /home/user/my-project/.workshop/<NAME>.yaml
The generated definition carries the runtime:
name: <NAME>
base: ubuntu@24.04
runtime: lxd-vm
Add the same key by hand to a definition you already wrote.
runtime accepts lxd-container and lxd-vm;
omitting it selects lxd-container.
Launch and verify¶
Launch the workshop the same way as any other:
$ workshop launch <NAME>
"<NAME>" launched
A virtual machine boots from a different base image than a container, so the first launch on a given base downloads that image.
Confirm what you got:
$ workshop info <NAME>
name: <NAME>
base: ubuntu@24.04
project: ~/my-project
hostname: <NAME>.my-project.wp
status: ready
runtime: lxd-vm
notes: --
The runtime line is the confirmation:
a container workshop reports runtime: lxd-container instead.
Manage the workshop¶
Stopping, starting, and removing a virtual machine workshop use the same commands as a container:
$ workshop stop <NAME>
"<NAME>" stopped
$ workshop start <NAME>
"<NAME>" started
$ workshop remove <NAME>
"<NAME>" removed
A running virtual machine workshop also starts again on its own after the host reboots, and it is reachable over SSH by hostname, in both cases exactly as a container workshop is. See Cross-workshop networking for reaching a workshop by hostname.
Limitations¶
Virtual machine workshops are not at parity with containers. The differences below change what you can do with one.
The runtime is fixed at launch¶
Editing runtime in the definition of a launched workshop
and refreshing it fails:
$ workshop refresh <NAME>
error: cannot refresh "<NAME>": cannot refresh "<NAME>": runtime changed from "lxd-vm" to "lxd-container"
Remove the workshop and launch it again to change the runtime.
SDK support depends on LXD¶
On LXD from the 6/stable channel,
a virtual machine workshop that declares an SDK is refused:
$ workshop refresh <NAME>
error: cannot refresh "<NAME>": cannot refresh "<NAME>": SDKs are currently unavailable for virtual machines
Switch LXD to 6/candidate as the prerequisites require.
Most interfaces are unsupported¶
Currently, virtual machine workshops only support the mount and secret interfaces.
Other interfaces will not be auto-connected and cannot be connected manually.
Virtual machine workshops can still install SDKs that contain unsupported plugs and slots, but these plugs and slots will not be listed in workshop connections.
Removing stopped workshops¶
Disconnecting a mount interface plug
requires the workshop to be running.
This can prevent removing a stopped workshop.
Either start the workshop before removing it,
or see How to purge malfunctioning workshops.
A future Workshop release will remove this limitation.
Virtual hardware is restrictive¶
Virtual machines are modeled on physical hardware, and have some of the same limitations. When the workshop starts, the following quantities are set in stone:
The number of processors.
Total system memory.
The root filesystem size.
Interfaces can be connected and disconnected while the workshop is running, but much like devices plugged into a physical machine, there’s a limit to the total number of interface connections.
The simplest way to avoid these limits is to disconnect unused interfaces. In some cases, Workshop uses the number of SDKs to predict hardware requirements; adding an SDK without many plugs or slots can help to compensate for one with several active connections.
See also¶
Explanation:
How-to guides:
Reference: