
smolvm v1.8.3
Tragbare, leichte, in sich geschlossene virtuelle Maschine.
smolvm
Software ausliefern und ausführen – mit Isolation standardmäßig.
Dies ist ein CLI-Tool, mit dem du:
- Benutzerdefinierte Linux-VMs lokal verwalten und ausführen kannst: Sub-Sekunden-Kaltstart, plattformübergreifend (macOS, Linux, Windows), elastische Speichernutzung.
- Eine zustandsbehaftete VM in eine einzelne Datei (.smolmachine) packen kannst, um sie auf jeder unterstützten Plattform wiederherzustellen.
Installation
# installieren (macOS + Linux)
curl -sSL https://smolmachines.com/install.sh | bash
# für Coding-Agenten – installieren und alle Befehle entdecken
curl -sSL https://smolmachines.com/install.sh | bash && smolvm --help
Oder lade es von GitHub Releases herunter und lege es in ~/.local/share/ ab.
Windows: Lade das Release windows-x86_64 herunter (enthält krun.dll + libkrunfw.dll), entpacke es und führe smolvm.exe aus. Erfordert die aktivierte Windows Hypervisor Platform (WHP)-Funktion.
Schnellstart
# einen Befehl in einer ephemeren VM ausführen (nach Beendigung bereinigt)
smolvm machine run --net --image alpine -- sh -c "echo 'Hello world from a microVM' && uname -a"
# interaktive Shell
smolvm machine run --net -it --image alpine -- /bin/sh
# innerhalb der VM: apk add sl && sl && exit
Smolfile
Eine Smolfile deklariert eine Maschine in TOML – das Äquivalent zu einer Dockerfile oder einer Cloud-init-Datei, aber für eine ganze VM: Image, Ressourcen, Netzwerkrichtlinie, Mounts, Ports und Setup-Befehle in einer einzigen eingecheckten Datei.
image = "python:3.12-alpine"
net = true
cpus = 4
memory = 4096
ports = ["8000:8000", "5173-5180:5173-5180"]
volumes = ["./src:/app"]
init = ["pip install -r /app/requirements.txt"]
[network]
allow_hosts = ["api.stripe.com", "pypi.org"]
[auth]
ssh_agent = true
smolvm machine create --name myvm -s Smolfile # oder --smolfile <PFAD>
smolvm machine start --name myvm
Port-Zuordnungen akzeptieren einen einzelnen Port ("8080"), eine explizite Zuordnung ("8080:80") oder gleich lange Eins-zu-eins-Bereiche ("5173-5180:5173-5180"). Eine Maschine kann höchstens 64 konkrete Zuordnungen veröffentlichen.
Unbekannte Schlüssel werden abgelehnt statt ignoriert, sodass ein Tippfehler bereits beim Erstellen fehlschlägt, anstatt stillschweigend nichts zu tun.
Häufige Schlüssel: image, cpus, memory, net, ports, volumes, env,
init, workdir, gpu, cuda, docker_socket, storage, overlay sowie die
Tabellen [network], [dev], [auth], [health], [restart], [service].
Eine Maschine in ein wiederverwendbares Image snapshotten
Du brauchst keine Dockerfile, um eine Umgebung zu erhalten. Richte eine Maschine nach Belieben ein – von Hand oder über eine Smolfile – und packe dann die gestoppte Maschine in ein .smolmachine-Artefakt und pushe es in eine beliebige OCI-Registry:
smolvm machine shell --name myvm # interaktiv installieren und konfigurieren
smolvm machine stop --name myvm
smolvm pack create --from-vm myvm -o myvm
smolvm pack push --file myvm.smolmachine ghcr.io/you/myvm:v1
Jeder kann es dann pullen und exakt dieselbe Maschine booten:
smolvm pack pull ghcr.io/you/myvm:v1
Funktionierende Smolfiles: python · node · docker-in-vm · local-llm · headless-browser · doom
Wofür das gedacht ist
Unvertrauenswürdigen Code sandboxen – führe unvertrauenswürdige Programme in einer hardware-isolierten VM aus. Host-Dateisystem, Netzwerk und Anmeldedaten sind durch eine Hypervisor-Grenze getrennt.
# Netzwerk ist standardmäßig aus – unvertrauenswürdiger Code kann nicht nach Hause telefonieren
smolvm machine run --image alpine -- nslookup example.com
# schlägt fehl – kein Netzwerkzugriff
# ausgehenden Datenverkehr einschränken – nur bestimmte Hosts zulassen
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://registry.npmjs.org
# funktioniert – erlaubter Host
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://google.com
# schlägt fehl – nicht in der Zulassungsliste
In portable ausführbare Dateien packen – verwandle jede Arbeitslast in eine eigenständige Binärdatei. Alle Abhängigkeiten sind vorinstalliert – kein Installationsschritt, keine Laufzeit-Downloads, bootet in <200ms.
smolvm pack create --image python:3.12-alpine -o ./python312
./python312 run -- python3 --version
# Python 3.12.x – isoliert, kein pyenv/venv/conda nötig
Lokale Container-Images verwenden – für CI, luftgekapselte Hosts und schnelle Iteration. Gib --image ein docker save / podman save-Archiv, pipe eines über stdin oder zeige auf ein entpacktes Rootfs-Verzeichnis. Die Image-Arbeit wird an deine Container-Tools delegiert; smolvm bootet nur das Ergebnis.
# lokal bauen, in der VM ausführen ohne push/pull
docker build -t myapp .
docker save myapp | smolvm machine run --image - -- ./app
# aus einer Archivdatei (bootet ohne Netzwerk)
smolvm machine run --image ./myapp.tar -- ./app
# aus einem bereits entpackten Rootfs-Verzeichnis
smolvm machine run --image ./rootfs/ -- ./app
Persistente Maschinen für die Entwicklung – erstellen, stoppen, starten. Installierte Pakete überleben Neustarts.
smolvm machine create --net --name myvm
smolvm machine start --name myvm
smolvm machine exec --name myvm -- apk add sl
smolvm machine exec --name myvm -it -- /bin/sh
# innerhalb: sl, ls, uname -a – 'exit' eingeben zum Verlassen
smolvm machine stop --name myvm
Git und SSH nutzen, ohne private Schlüssel in den Gast zu kopieren. Leite deinen Host-SSH-Agent in die VM weiter. Der Gast kann den Agent bitten, mit jedem weitergeleiteten Schlüssel zu signieren, solange der Socket verfügbar ist – leite ihn also nur an Arbeitslasten weiter, denen du vertraust. Erfordert einen auf dem Host laufenden SSH-Agent (ssh-add -l zum Prüfen).
smolvm machine run --ssh-agent --net --image alpine -- sh -c "apk add -q openssh-client && ssh-add -l"
# listet deine Host-Schlüssel auf; privates Schlüsselmaterial bleibt im Host-Agent
smolvm machine exec --name myvm -- git clone [email protected]:org/private-repo.git
Umgebungen in einer Datei deklarieren – siehe Smolfile oben für
reproduzierbare Maschinenkonfiguration und zum Snapshotten einer konfigurierten Maschine in ein
wiederverwendbares .smolmachine-Image ohne eine Dockerfile zu schreiben.
So funktioniert es
Jede Arbeitslast läuft in einer hardware-virtualisierten VM mit eigenem Gast-Kernel auf Hypervisor.framework (macOS), KVM (Linux) oder der Windows Hypervisor Platform (Windows). libkrun ist der VMM und libkrunfw liefert den Gast-Kernel. Packe es in eine .smolmachine und es läuft überall dort, wo die Host-Architektur übereinstimmt – mit null Abhängigkeiten.
Images verwenden das OCI-Format – derselbe offene Standard, den Docker verwendet. Jedes Image auf Docker Hub, ghcr.io oder anderen OCI-Registries kann gepullt und als MicroVM gebootet werden. Kein Docker-Daemon erforderlich.
Standardwerte: 4 vCPUs, 8 GiB RAM. Der Speicher ist elastisch über virtio-Balloon – der Host reserviert nur, was der Gast tatsächlich nutzt, und gibt den Rest automatisch frei. vCPU-Threads schlafen im Hypervisor, wenn sie im Leerlauf sind, sodass Überprovisionierung nahezu keine Kosten verursacht. Überschreiben mit --cpus und --mem.
Sicherheitsmodell
smolvm stärkt die Gast/Host-Grenze, indem es jeder Arbeitslast eine separate VM und einen separaten Gast-Kernel gibt. Es ist für sich genommen keine gehärtete Multi-User-Kontrollebene:
- Die
smolvm-CLI- und VMM-Prozesse laufen mit den Berechtigungen des aufrufenden Host-Benutzers. Dieses Benutzerkonto, das Host-Betriebssystem, das Hypervisor-Backend, libkrun und smolvm gehören zur vertrauenswürdigen Rechenbasis. - Host-Verzeichnisse, die mit
--volumeübergeben werden, sind absichtlich mit dem angeforderten Zugriff für den Gast freigegeben. Mounte keine Geheimnisse oder sensible Pfade in eine unvertrauenswürdige Arbeitslast. --ssh-agentkopiert kein privates Schlüsselmaterial in den Gast, gewährt dem Gast aber Zugriff auf den weitergeleiteten Agent-Socket und damit die Möglichkeit, Signaturen anzufordern, solange die VM läuft.- Netzwerk ist standardmäßig deaktiviert. Das Aktivieren von
--net, Port-Weiterleitung oder Host-Diensten erweitert die erreichbare Oberfläche der Arbeitslast. - Bei eigenständiger lokaler Nutzung sind smolvms Zustands- und Steuer-Endpunkte auf die Umgebung des aufrufenden Benutzers beschränkt. Für feindselige lokale Mitbewohner füge Host-Ebene-Kontotrennung und OS-Eindämmung um den VMM-Prozess hinzu. Dieser Abschnitt beschreibt nicht die separate smolmachines-Cloud-Kontrollebene oder deren Mandantenisolationsgarantien.
- Release-Archive veröffentlichen SHA-256-Prüfsummen und der Installer lehnt eine Abweichung ab, wenn die Prüfsummendatei verfügbar ist. Releases sind derzeit weder signiert noch mit Herkunftsnachweisen versehen, und der Installer erlaubt die Installation, wenn die Prüfsummendatei nicht heruntergeladen werden kann.
Behandle Root im Gast als unvertrauenswürdig. Die VM-Grenze begrenzt seinen direkten Zugriff auf den Host, während jede explizit weitergeleitete Fähigkeit – einschließlich Mounts, Netzwerkzugriff, Ports und SSH-Agent-Zugriff – Teil der Autorität der Arbeitslast wird.
Vergleich
| smolvm | Container | Colima | QEMU | Firecracker | Kata | |
|---|---|---|---|---|---|---|
| Arbeitslast-Grenze | VM + Gast-Kernel | Namespace + gemeinsamer Kernel | Namespace in gemeinsamer VM | VM + Gast-Kernel | VM + Gast-Kernel | VM pro Container |
| Bootzeit | <200ms | ~100ms | ~Sekunden | ~15-30s | <125ms | ~500ms |
| Architektur | Bibliothek (libkrun) | Daemon | Daemon (in VM) | Prozess | Prozess | Laufzeit-Stack |
| VMs pro Arbeitslast | Ja | Nein | Nein (gemeinsam) | Ja | Ja | Ja |
| macOS nativ | Ja | Über Docker-VM | Ja (krunkit) | Ja | Nein | Nein |
| Einbettbares SDK | Ja | Nein | Nein | Nein | Nein | Nein |
| Portable Artefakte | .smolmachine | Images (brauchen Daemon) | Nein | Nein | Nein | Nein |
Plattformunterstützung
| Host | Gast | Anforderungen |
|---|---|---|
| macOS Apple Silicon | arm64 Linux | macOS 11+ |
| macOS Intel | x86_64 Linux | macOS 11+ (ungetestet) |
| Linux x86_64 | x86_64 Linux | KVM (/dev/kvm) |
| Linux aarch64 | aarch64 Linux | KVM (/dev/kvm) |
| Windows x86_64 | x86_64 Linux | Windows Hypervisor Platform (WHP) aktiviert |
Bekannte Einschränkungen
- Netzwerk ist opt-in (
--netbeimachine create). Nur TCP/UDP, kein ICMP. - Volume-Mounts: nur Verzeichnisse (keine einzelnen Dateien). Das Mounten unter
/workspace(-v /host/dir:/workspace) hat Vorrang vor dem Standard-Speicherdisk-Workspace – dein Host-Verzeichnis wird stattdessen verwendet. - macOS: Die Binärdatei muss mit Hypervisor.framework-Berechtigungen signiert sein (
com.apple.security.hypervisor). Das ausgelieferte Release ist es; eine neu signierte oder frisch gebaute Binärdatei verliert sie stillschweigend und jeder VM-Start schlägt dann mitkrun_start_enter returned: -22 (EINVAL)fehl. Signiere sie neu (ad-hoc ist in Ordnung):codesign --force --sign - --entitlements hv.entitlements <smolvm-bin>wobeihv.entitlementseine plist ist, die<key>com.apple.security.hypervisor</key><true/>enthält. --ssh-agenterfordert einen auf dem Host laufenden SSH-Agent (SSH_AUTH_SOCKmuss gesetzt sein).- GPU-Beschleunigung erfordert libkrun, das mit
GPU=1gebaut wurde, sowie virglrenderer + einen Vulkan-Treiber auf dem Host (siehe GPU-Beschleunigung unten). - Windows:
--netfunktioniert wie auf anderen Plattformen (virtio-net mit eingehender Port-Weiterleitung; TSI für reine Outbound-VMs), ebenso wiemachine exec/ interaktive Sitzungen undmachine stats. Noch nicht auf Windows verfügbar: GPU-Beschleunigung undmachine fork/ Snapshot. Pack create benötigtstorage-template.ext4/overlay-template.ext4nebensmolvm.exe(Windows hat kein Host-mkfs.ext4).
GPU-Beschleunigung
smolvm stellt den Host-GPUs den Gästen über virtio-gpu / Venus (Vulkan-über-virtio) bereit. Gast-Arbeitslasten sehen ein echtes Vulkan-Gerät; auf Linux + Intel rendert das als:
ANGLE (Intel, Vulkan 1.4 (Virtio-GPU Venus (Intel(R) UHD Graphics ...)), venus)
Host-Anforderungen
macOS – virglrenderer und MoltenVK sind in der smolvm-Distribution enthalten. Keine zusätzlichen Installationen nötig.
Linux – virglrenderer und ein Host-Vulkan-Treiber müssen über den Systempaketmanager installiert werden:
| Distro | Pakete |
|---|---|
| Alpine | apk add virglrenderer mesa-vulkan-intel (oder mesa-vulkan-ati für AMD) |
| Debian/Ubuntu | apt install virglrenderer0 mesa-vulkan-drivers |
virglrenderer hängt von libEGL und libdrm aus dem Host-GPU-Treiber-Stack ab – diese sind hardwarespezifisch und können nicht gebündelt werden. Jeder GPU-fähige Linux-Host hat sie bereits über seinen GPU-Treiber installiert.
Verwendung
# CLI
smolvm machine run --gpu --image alpine -- vulkaninfo --summary
# Smolfile
# gpu = true
# gpu_vram = 2048 # MiB, Standard 4096
Der Gast-Vulkan-Loader muss auf das virtio-ICD zeigen:
export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/virtio_icd.x86_64.json
Headless-Browser-Beispiel
Siehe examples/headless-browser/ für ein funktionierendes Chromium-Setup mit ANGLE + Venus für hardwarebeschleunigtes WebGL in einer Headless-VM.
CUDA-API-Remoting
--gpu und --cuda bieten unterschiedliche Schnittstellen. --gpu stellt Vulkan über virtio-gpu / Venus bereit; es bietet kein CUDA. --cuda aktiviert CUDA-API-Remoting: treiberlose Gast-Shims leiten CUDA-Aufrufe über vsock an einen Host-Prozess weiter, der sie über den NVIDIA-Treiber des Hosts ausführt.
CUDA-Remoting erfordert eine NVIDIA-GPU und einen funktionierenden NVIDIA-Treiber auf dem Host. Es ist kein GPU-Passthrough: Der Gast erhält weder das physische Gerät noch einen NVIDIA-Treiber.
Fork-lastige Linux-Hosts sollten einen Kernel mit dem Upstream-KVM-Fix
916b7f4 verwenden.
Betroffene Kernel können beim ersten KVM_RUN intermittierend ENOMEM melden, selbst
bei reichlich Host-Speicher; smolvm reduziert die Exposition und ersetzt einen fehlgeschlagenen Worker,
aber das Kernel-Update ist die endgültige Lösung.
Die VM-Grenze isoliert weiterhin CPU, Speicher und Dateisystem der Arbeitslast. Der GPU-Zugriff wird durch Host-Prozesse und die gemeinsame Host-GPU vermittelt, sodass die GPU-Isolation auf Prozessebene bleibt und keine Hardware- oder VM-Grenze darstellt. Behandle CUDA-Remoting nicht als gehärtete Multi-Tenant-GPU-Isolationsgrenze.
Siehe GPU access by API remoting: how a driverless microVM runs CUDA für das Design, die Abwägungen und den Vergleich mit Passthrough.
Entwicklung
Siehe docs/DEVELOPMENT.md.
Apache-2.0 · erstellt von @binsquare · twitter · github