Local Examples
These examples use the v1.7.1 nested CLI. Run smolvm COMMAND --help to check flags against the version installed on your host.
One-off command without networking
smolvm machine run --image alpine -- sh -c \
"printf 'isolated\n' && uname -a" The VM and its filesystem changes are removed when the command exits.
Interactive Alpine shell
smolvm machine run --net -it --image alpine -- /bin/sh Inside the VM:
apk add git
git --version
exit Restrict network egress
smolvm machine run \
--net \
--image alpine \
--allow-host registry.npmjs.org \
-- wget -q -O /dev/null https://registry.npmjs.org Networking is off unless --net is set. The allow-list limits the enabled network path to the declared host.
Persistent Python environment
smolvm machine create \
--name pydev \
--image python:3.12-alpine \
--net
smolvm machine start --name pydev
smolvm machine exec --name pydev -- pip install requests
smolvm machine exec --name pydev -- \
python3 -c "import requests; print(requests.__version__)"
smolvm machine stop --name pydev Start the same machine later:
smolvm machine start --name pydev
smolvm machine exec --name pydev -- \
python3 -c "import requests; print(requests.__version__)" Run code from a host directory
smolvm machine run \
--image python:3.12-alpine \
--volume "$PWD:/app" \
-- python3 /app/main.py The guest can read and write the mounted host directory. Do not use sensitive host directories with untrusted code.
Copy code into a persistent machine
smolvm machine create --name job --image python:3.12-alpine
smolvm machine start --name job
smolvm machine cp ./job.py job:/workspace/job.py
smolvm machine exec --name job -- python3 /workspace/job.py
smolvm machine cp job:/workspace/result.json ./result.json
smolvm machine stop --name job Use a volume mount instead of machine cp for transfers at or above 4 GiB.
Run a locally built OCI image
docker build -t myapp .
docker save myapp | smolvm machine run --image - -- ./app Or save the archive first:
docker save myapp -o myapp.tar
smolvm machine run --image ./myapp.tar -- ./app smolvm boots the image as a VM. It does not build Dockerfiles.
Pack a preinstalled runtime
smolvm pack create --image python:3.12-alpine -o ./python312
./python312 run -- python3 --version See Pack and .smolmachine CLI for stopped-machine packing and persistent machines created from artifacts.
Stream a long-running command
smolvm machine start --name pydev
smolvm machine exec --stream --name pydev -- python3 /workspace/train.py --stream prints output as it arrives.
Forward the host SSH agent
ssh-add -l
smolvm machine run \
--ssh-agent \
--net \
--image alpine \
-- sh -c "apk add -q openssh-client && ssh-add -l" Private key material stays in the host agent, but the guest can request signatures while the forwarded socket is available. Use this only with workloads you trust.
Publish a guest port
smolvm machine run \
--net \
--image python:3.12-alpine \
--port 8000:8000 \
-- python3 -m http.server 8000 The service is reachable through host port 8000 while the ephemeral machine is running.
Clean up
smolvm machine stop --name pydev
smolvm machine delete --name pydev
smolvm machine delete --name job Use machine stop when you want to keep disk state. Use machine delete when you want to remove the named machine.