
Tragbare, leichte, in sich geschlossene virtuelle Maschine.
Software ausliefern und ausführen – mit Isolation standardmäßig.
Dies ist ein CLI-Tool, mit dem du:
# 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 ab.
~/.local/share/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.
# 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
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].
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
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.
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.
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:
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.--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-agent kopiert 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.--net, Port-Weiterleitung oder Host-Diensten erweitert die erreichbare Oberfläche der Arbeitslast.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.
| 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 |
| 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 |
--net bei machine create). Nur TCP/UDP, kein ICMP./workspace (-v /host/dir:/workspace) hat Vorrang vor dem Standard-Speicherdisk-Workspace – dein Host-Verzeichnis wird stattdessen verwendet.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 mit krun_start_enter returned: -22 (EINVAL) fehl. Signiere sie neu (ad-hoc ist in Ordnung): codesign --force --sign - --entitlements hv.entitlements <smolvm-bin> wobei hv.entitlements eine plist ist, die <key>com.apple.security.hypervisor</key><true/> enthält.--ssh-agent erfordert einen auf dem Host laufenden SSH-Agent (SSH_AUTH_SOCK muss gesetzt sein).GPU=1 gebaut wurde, sowie virglrenderer + einen Vulkan-Treiber auf dem Host (siehe GPU-Beschleunigung unten).--net funktioniert wie auf anderen Plattformen (virtio-net mit eingehender Port-Weiterleitung; TSI für reine Outbound-VMs), ebenso wie machine exec / interaktive Sitzungen und machine stats. Noch nicht auf Windows verfügbar: GPU-Beschleunigung und machine fork / Snapshot. Pack create benötigt storage-template.ext4 / overlay-template.ext4 neben smolvm.exe (Windows hat kein Host-mkfs.ext4).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)
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.
# 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
Siehe examples/headless-browser/ für ein funktionierendes Chromium-Setup mit ANGLE + Venus für hardwarebeschleunigtes WebGL in einer Headless-VM.
--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.
Siehe docs/DEVELOPMENT.md.
Apache-2.0 · erstellt von @binsquare · twitter · github