Skip to main content
Custom images let you start SmolVM with your own tools already inside. You can add packages and files once, then reuse that setup every time you create an isolated machine. This guide starts with one working path. After that, it shows how to run commands inside the image, how the CLI fits in, and where to go when you need deeper control.

What You Can Build

Use custom images when the default SmolVM images need extra software or a different startup process.
A root filesystem, often shortened to rootfs, is the disk image that contains the operating system files inside the sandbox.

Before You Start

You need:
  • Docker installed and running, because the Linux image builders use Docker to assemble files.
  • A working VM runner. SmolVM calls this a backend. Use QEMU for the broadest local path on macOS and Linux. Use Firecracker on Linux when you want the production Linux runner.
  • Python with smolvm installed.
Check the host before building:

Boot One Dockerfile Image

In this chapter, you build a tiny Alpine image and boot it. The image starts and stays running. It is intentionally boot-only, so the first success signal is the VM ID.
1

Create a Python file

Create custom_image.py in any directory where your Python environment can import smolvm.
custom_image.py
2

Run it

Run the file from the same directory:
You should see output like Started sbx-8f3a2c1b. The exact ID is generated for each VM.
What happened:
  • DockerRootfsBuilder turned the Dockerfile into a raw ext4 disk.
  • DirectKernelBoot() used SmolVM’s default Linux boot settings, including /init.
  • SmolVM.from_image(...) created a private per-VM disk and started the sandbox.

Run Commands Inside The Image

The Dockerfile image above proves that a custom disk can boot. To run commands from the host with vm.run(...), the guest, which is the operating system inside the sandbox, needs a control path. The easiest path is ImageBuilder, which creates an SSH-ready Linux image. SSH is the standard remote shell protocol SmolVM can use to send commands into the sandbox.
1

Create a command-ready image

Create command_ready_image.py:
command_ready_image.py
2

Run it

The command prints hello-from-custom-image.
Choose this path when your first goal is command execution, file upload, environment variables, or port forwarding from the SDK.

Use The CLI

Use the SDK, which is the Python API, for Dockerfile-backed Linux images. Use the CLI, which is the command line, for built-in Linux images, preset images, and Windows image building. Create and inspect a built-in Ubuntu sandbox from the CLI:
For Windows image building, start with the built-in help:
See the Windows image CLI reference for the full ISO-to-qcow2 flow.

Add More Control

Most users can stop after Chapters 1-3. Use this section when you need to keep a custom Dockerfile as the source of truth, resize disks, or boot an existing image file.

Build From A Dockerfile

DockerRootfsBuilder is the main SDK API for Dockerfile-backed Linux images. Use it when you want to own the packages, files, and init process inside the guest. Important options:
Set ssh_capable=True only when your image starts SSH during boot and accepts the ssh_user, ssh_key_path, or ssh_password you pass to SmolVM.

Launch A BootImage

BootImage is a small Python object that describes a bootable disk. DockerRootfsBuilder.ensure(...) returns one for you. Pass that image to SmolVM.from_image(...) when you want normal VM settings:
  • memory_mb for memory size
  • vcpus for CPU count
  • backend to choose QEMU or Firecracker
  • port_forwards for QEMU slirp networking
  • disk_size_mb to grow the per-VM disk
  • grow_filesystem=True to expand raw ext4 filesystems on the host
For qcow2 images, SmolVM can grow the virtual disk size. The guest operating system remains responsible for growing its partition or filesystem.

Boot An Existing Disk

Use BootImage directly when you already have a disk image on the host. Common cases:
  • Raw ext4 Linux image with a kernel loaded by SmolVM
  • QEMU qcow2 cloud image that boots through firmware
  • Windows qcow2 image built with smolvm windows build-image
See the BootImage API reference for complete constructor fields and validation rules.

Keep Builds Fast

SmolVM caches built images under ~/.smolvm/images/. Reusing the same Dockerfile, build args, context files, target architecture, and rootfs size reuses the cached rootfs. Run this when old release caches take up space:
If the preview looks right, run:

Boot Settings

Boot settings are the values passed to Linux before it starts. Most users should use the defaults:
  • DirectKernelBoot() for Dockerfile-built Linux images.
  • SSH_BOOT_ARGS for ImageBuilder images.
  • FirmwareBoot() for QEMU images that already contain their own bootloader.
Use custom boot settings only when you know the guest needs a different root device, init path, console, or extra kernel argument. Related references:

Troubleshooting

Check Docker first:
On macOS, start Docker Desktop. On Ubuntu, install Docker with sudo apt install docker.io and make sure the daemon is running.
Use an SSH-ready image from ImageBuilder, or add SSH or a guest agent to your Dockerfile image. A boot-only image can start successfully while still leaving command execution unavailable.
Use grow_filesystem=True for raw ext4 images. For qcow2 images, grow the partition or filesystem from inside the guest operating system.

Next Steps

BootImage API

Describe bootable root filesystems, kernels, firmware images, and boot helpers.

DockerRootfsBuilder API

Build and cache raw ext4 root filesystems from Dockerfiles.

SmolVM API

Launch custom images with CPU, memory, networking, and disk sizing options.

Windows images

Build a reusable Windows qcow2 image from an ISO.
Last modified on June 24, 2026