Skip to content

How Provisioning Works

sand splits provisioning into two passes so the expensive work happens once, not on every VM. This is the same everywhere a VM can run — on your own machine, on a remote host, or on Proxmox.

graph TD
    A[sand create] --> B{Base image exists?}
    B -- no --> C[Build the base image: heavy install]
    C --> D[Stop the base image]
    B -- yes --> D
    D --> E[Clone the base → grow disk]
    E --> F[Finalize: selected agents, hostname, git identity, optional repo clone]
    F --> G[Ready: restart only if required]

The base image

The first time you create a VM, sand runs a heavy install into a stopped VM named sandbar-base. This installs development tools and shared runtimes. Coding agents are excluded from the base. See Available Tools for the full toolchain.

Because the base image carries no identity or secrets, it's safe to keep around and reuse indefinitely — sand rebuilds it automatically if the underlying provisioning logic has changed since it was built, or you can force a rebuild yourself with sand create --rebuild (or by deleting sandbar-base and creating a new VM).

Each place you run VMs gets its own base image, built the first time you create a VM there. A base image on your laptop and one on a server are separate, and neither is copied to the other.

Cloning

Every VM after the first is a copy of the stopped base image, grown to the disk size you asked for. Copying a stopped VM is far cheaper than reinstalling the whole stack, which is what makes each new VM fast.

Finalize

A clone isn't ready to use yet — it's still an anonymous copy of the base image. Finalize installs current releases of the selected agents, sets the VM's hostname, writes your git identity, and optionally clones a project repository. OS upgrades happen during base maintenance; the VM restarts only when the guest reports a reboot is required.

Reset repeats the per-VM installs using that VM's recorded selections. The optional agent preservation checkbox keeps settings and files across reset; executable releases are installed fresh. When upgrading from an older sand, base maintenance removes legacy agent installs before cloning. Changing agent choices alone does not invalidate the base's dependency stamp.

Why the split

Doing the heavy install once and sharing it across every VM keeps VM creation fast without compromising isolation: identity is applied per-VM at finalize time, so the shared base image never contains anyone's secrets or git configuration.

How each backend does it

The shape above is identical everywhere; only the mechanics differ.

On your machine or a remote host On Proxmox
Runs VMs with Lima, via limactl The Proxmox REST API
The base image is a stopped Lima instance a PVE template, built from a cloud image
A new VM is limactl clone of it a PVE clone of that template
sand reaches the guest over limactl shell, or SSH for a remote host SSH, to the address the guest agent reports

For a remote host, sand runs the same limactl commands it would run locally — it only changes where they run. See Where VMs Run.