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: hostname, git identity, apt upgrade, optional repo clone]
    F --> G[Restart → ready]

The base image

The first time you create a VM, sand runs a heavy install into a stopped VM named sandbar-base. This installs the dev tools, Claude Code, and everything else that every VM needs. 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. A light finalize pass sets the VM's hostname, writes your git identity into it, runs apt upgrade, and optionally clones a project repository into it. The VM restarts once at the end of finalize and is then ready to use.

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.