Skip to main content
A golden image is a committed VM snapshot with your tools, dependencies, and configuration pre-installed. Boot from it to get a working environment in seconds instead of spending minutes on setup every time.

When You Need a Custom Golden Image

Use the stock default rootfs when your project has simple needs (standard Ubuntu packages, small dependency trees). Build a custom golden when:
  • Installation takes too long: npm install, pip install, or cargo build takes more than a few minutes on a fresh VM
  • System dependencies are required: Your project needs apt install packages not in the base Ubuntu image
  • Version pinning matters: You need exact versions of Node, Python, Rust, or system libraries
  • Build toolchains are heavy: Custom compilers, cross-compilation tools, CUDA/ROCm
  • Caches improve performance: Pre-populated package manager caches, pre-built indexes, database dumps
  • Agent tooling is needed: pi, Claude Code, or other agents pre-installed with the RPC scaffold ready

The Build Process

Step 1: Start a Builder VM

Use generous resources for the build. You’ll commit a lean snapshot at the end.
Edit vers.toml for build resources:

Step 2: Install Everything

Inside the VM, set up DNS and install your stack:

Example: Node.js Agent Environment

Example: Python ML Environment

Example: Haskell Build Environment

Step 3: Set Up Agent RPC Scaffold (Optional)

If the golden image will run coding agents, set up the FIFO infrastructure and systemd auto-start:
Create systemd units for auto-start on VM restore:
Why .path units? Vers snapshots preserve memory state, not boot state. When a VM is restored from a commit, systemd doesn’t re-run start jobs. The .path unit watches for /etc/environment being written (which Vers does on every VM create), triggering service startup with fresh environment variables.The .path unit must be active (not just enabled) at commit time, or it won’t fire on restore.

Step 4: Hygiene Pass

Before committing, clean secrets and regenerate identity:
Vers snapshots capture everything: RAM, process state, disk, logs. Any secret present at commit time is baked into the image and available to anyone who boots from it. Always stop services and clear /etc/environment before committing.
Exit the VM:

Step 5: Commit and Tag

Save the commit ID. You can now boot new VMs from this snapshot:

Step 6: Clean Up the Builder

The builder VM used generous resources. Delete it once you have the commit:

Using Golden Images

Boot from a Commit ID

Share with Team Members

Share the commit ID directly. Anyone with Vers access can boot from it:

Updating Golden Images

When dependencies change, build a new golden image:
  1. Boot a fresh VM from the old golden image
  2. Update what changed (npm update, apt upgrade, etc.)
  3. Re-run the hygiene pass
  4. Commit as a new snapshot
Keep a record of commit IDs and what they contain. A simple convention:

Key Principles

Stop services before commit. Running services hold environment variables in memory. When someone boots from the snapshot, the service resumes with the old env vars, ignoring the new VM’s /etc/environment. Always stop, commit, and let systemd .path units restart with fresh env. Regenerate SSH host keys. Without this, every VM from the snapshot has the same SSH identity. Security risk. Clear /etc/environment. Vers writes environment variables here on VM create. If the file already has content at commit time, the .path unit may not detect a change (same content = no mtime change = no trigger). Size the builder generously, the image inherits only what’s on disk. A 30 GB builder VM with 8 GB RAM can produce a golden image that runs fine on 2 GB RAM and 10 GB disk, as long as the installed software fits.

See Also