
smolvm v1.8.3
Máquina virtual portátil, leve e autossuficiente.
smolvm
Distribua e execute software com isolamento por padrão.
Esta é uma ferramenta de CLI que permite:
- Gerenciar e executar máquinas virtuais Linux personalizadas localmente com: inicialização a frio em menos de um segundo, multiplataforma (macOS, Linux, Windows), uso elástico de memória.
- Empacotar uma máquina virtual com estado em um único arquivo (.smolmachine) para reidratar em qualquer plataforma suportada.
Instalação
# instalar (macOS + Linux)
curl -sSL https://smolmachines.com/install.sh | bash
# para agentes de codificação — instalar + descobrir todos os comandos
curl -sSL https://smolmachines.com/install.sh | bash && smolvm --help
Ou baixe dos GitHub Releases e coloque-o em ~/.local/share/.
Windows: baixe o release windows-x86_64 (inclui krun.dll + libkrunfw.dll), descompacte-o e execute smolvm.exe. Requer o recurso Windows Hypervisor Platform (WHP) habilitado.
Início Rápido
# executar um comando em uma VM efêmera (limpa após a saída)
smolvm machine run --net --image alpine -- sh -c "echo 'Hello world from a microVM' && uname -a"
# shell interativo
smolvm machine run --net -it --image alpine -- /bin/sh
# dentro da VM: apk add sl && sl && exit
Smolfile
Um Smolfile declara uma máquina em TOML — o equivalente a um Dockerfile ou um
arquivo cloud-init, mas para uma VM inteira: imagem, recursos, política de rede,
montagens, portas e comandos de configuração em um único arquivo versionado.
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 # ou --smolfile <PATH>
smolvm machine start --name myvm
Os mapeamentos de porta aceitam uma única porta ("8080"), um mapeamento explícito ("8080:80") ou intervalos um-para-um de comprimento igual ("5173-5180:5173-5180"). Uma máquina pode publicar no máximo 64 mapeamentos concretos.
Chaves desconhecidas são rejeitadas em vez de ignoradas, portanto um erro de digitação falha no momento da criação em vez de silenciosamente não fazer nada.
Chaves comuns: image, cpus, memory, net, ports, volumes, env,
init, workdir, gpu, cuda, docker_socket, storage, overlay e as
tabelas [network], [dev], [auth], [health], [restart], [service].
Criar um snapshot de uma máquina em uma imagem reutilizável
Você não precisa de um Dockerfile para manter um ambiente. Configure uma máquina como preferir —
manualmente ou a partir de um Smolfile — depois empacote a máquina parada em um
artefato .smolmachine e envie-o para qualquer registro OCI:
smolvm machine shell --name myvm # instalar e configurar interativamente
smolvm machine stop --name myvm
smolvm pack create --from-vm myvm -o myvm
smolvm pack push --file myvm.smolmachine ghcr.io/you/myvm:v1
Qualquer pessoa pode então puxá-lo e iniciar exatamente a mesma máquina:
smolvm pack pull ghcr.io/you/myvm:v1
Smolfiles funcionais: python · node · docker-in-vm · local-llm · headless-browser · doom
Use Para Isso
Isolar código não confiável — execute programas não confiáveis em uma VM isolada por hardware. O sistema de arquivos do host, a rede e as credenciais são separados por uma fronteira de hipervisor.
# a rede está desligada por padrão — código não confiável não pode se comunicar
smolvm machine run --image alpine -- nslookup example.com
# falha — sem acesso à rede
# restrinja a saída — permita apenas hosts específicos
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://registry.npmjs.org
# funciona — host permitido
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://google.com
# falha — não está na lista de permitidos
Empacotar em executáveis portáteis — transforme qualquer carga de trabalho em um binário autocontido. Todas as dependências são pré-embutidas — sem etapa de instalação, sem downloads em tempo de execução, inicializa em <200ms.
smolvm pack create --image python:3.12-alpine -o ./python312
./python312 run -- python3 --version
# Python 3.12.x — isolado, sem necessidade de pyenv/venv/conda
Usar imagens de contêiner locais — para CI, hosts isolados e iteração rápida. Alimente --image com um arquivo docker save / podman save, canalize um via stdin ou aponte para um diretório rootfs descompactado. O trabalho de imagem é delegado às suas ferramentas de contêiner; o smolvm apenas inicia o resultado.
# compilar localmente, executar na VM sem push/pull
docker build -t myapp .
docker save myapp | smolvm machine run --image - -- ./app
# a partir de um arquivo (inicia sem rede)
smolvm machine run --image ./myapp.tar -- ./app
# a partir de um diretório rootfs já descompactado
smolvm machine run --image ./rootfs/ -- ./app
Máquinas persistentes para desenvolvimento — crie, pare, inicie. Os pacotes instalados sobrevivem a reinicializações.
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
# dentro: sl, ls, uname -a — digite 'exit' para sair
smolvm machine stop --name myvm
Use git e SSH sem copiar chaves privadas para o convidado. Encaminhe o agente SSH do seu host para a VM. O convidado pode pedir ao agente para assinar com qualquer chave encaminhada enquanto o socket estiver disponível, portanto encaminhe-o apenas para cargas de trabalho em que você confia. Requer um agente SSH em execução no seu host (ssh-add -l para verificar).
smolvm machine run --ssh-agent --net --image alpine -- sh -c "apk add -q openssh-client && ssh-add -l"
# lista as chaves do seu host; o material da chave privada permanece no agente do host
smolvm machine exec --name myvm -- git clone [email protected]:org/private-repo.git
Declare ambientes em um arquivo — veja Smolfile acima para
configuração de máquina reproduzível e, para criar um snapshot de uma máquina configurada em uma
imagem .smolmachine reutilizável sem escrever um Dockerfile.
Como Funciona
Cada carga de trabalho é executada em uma VM virtualizada por hardware com seu próprio kernel convidado em Hypervisor.framework (macOS), KVM (Linux) ou Windows Hypervisor Platform (Windows). libkrun é o VMM e libkrunfw fornece o kernel convidado. Empacote-o em um .smolmachine e ele será executado em qualquer lugar onde a arquitetura do host corresponda, com zero dependências.
As imagens usam o formato OCI — o mesmo padrão aberto que o Docker usa. Qualquer imagem no Docker Hub, ghcr.io ou outros registros OCI pode ser puxada e iniciada como uma microVM. Nenhum daemon Docker é necessário.
Padrões: 4 vCPUs, 8 GiB de RAM. A memória é elástica via virtio balloon — o host só compromete o que o convidado realmente usa e recupera o restante automaticamente. As threads de vCPU dormem no hipervisor quando ociosas, então o superprovisionamento tem custo quase zero. Substitua com --cpus e --mem.
Modelo de Segurança
O smolvm fortalece a fronteira convidado/host dando a cada carga de trabalho uma VM separada e um kernel convidado. Ele não é, por si só, um plano de controle multiusuário endurecido:
- Os processos da CLI
smolvme do VMM são executados com as permissões do usuário host que os invoca. Essa conta de usuário, o sistema operacional do host, o backend do hipervisor, o libkrun e o smolvm estão na base de computação confiável. - Diretórios do host passados com
--volumesão intencionalmente expostos ao convidado com o acesso solicitado. Não monte segredos ou caminhos sensíveis em uma carga de trabalho não confiável. --ssh-agentnão copia material de chave privada para o convidado, mas concede ao convidado acesso ao socket do agente encaminhado e, portanto, a capacidade de solicitar assinaturas enquanto a VM estiver em execução.- A rede está desabilitada por padrão. Habilitar
--net, encaminhamento de porta ou serviços do host expande a superfície alcançável da carga de trabalho. - No uso local autônomo, o estado e os endpoints de controle do smolvm são limitados ao ambiente do usuário que os invoca. Para co-inquilinos locais hostis, adicione separação de contas em nível de host e confinamento do SO em torno do processo do VMM. Esta seção não descreve o plano de controle de nuvem separado do smolmachines nem suas garantias de isolamento de inquilinos.
- Os arquivos de release publicam somas de verificação SHA-256 e o instalador rejeita uma incompatibilidade quando o arquivo de soma de verificação está disponível. Os releases não são atualmente assinados nem acompanhados de atestados de proveniência, e o instalador permite a instalação quando o arquivo de soma de verificação não pode ser baixado.
Trate o root no convidado como não confiável. A fronteira da VM limita seu acesso direto ao host, enquanto cada capacidade explicitamente encaminhada, incluindo montagens, acesso à rede, portas e acesso ao agente SSH, torna-se parte da autoridade da carga de trabalho.
Comparação
| smolvm | Containers | Colima | QEMU | Firecracker | Kata | |
|---|---|---|---|---|---|---|
| Fronteira da carga de trabalho | VM + kernel convidado | Namespace + kernel compartilhado | Namespace dentro de VM compartilhada | VM + kernel convidado | VM + kernel convidado | VM por contêiner |
| Tempo de inicialização | <200ms | ~100ms | ~segundos | ~15-30s | <125ms | ~500ms |
| Arquitetura | Biblioteca (libkrun) | Daemon | Daemon (na VM) | Processo | Processo | Pilha de runtime |
| VMs por carga de trabalho | Sim | Não | Não (compartilhada) | Sim | Sim | Sim |
| Nativo no macOS | Sim | Via VM Docker | Sim (krunkit) | Sim | Não | Não |
| SDK incorporável | Sim | Não | Não | Não | Não | Não |
| Artefatos portáteis | .smolmachine | Imagens (precisam de daemon) | Não | Não | Não | Não |
Suporte de Plataforma
| Host | Convidado | Requisitos |
|---|---|---|
| macOS Apple Silicon | Linux arm64 | macOS 11+ |
| macOS Intel | Linux x86_64 | macOS 11+ (não testado) |
| Linux x86_64 | Linux x86_64 | KVM (/dev/kvm) |
| Linux aarch64 | Linux aarch64 | KVM (/dev/kvm) |
| Windows x86_64 | Linux x86_64 | Windows Hypervisor Platform (WHP) habilitado |
Limitações Conhecidas
- A rede é opcional (
--netnomachine create). Apenas TCP/UDP, sem ICMP. - Montagens de volume: apenas diretórios (sem arquivos individuais). Montar em
/workspace(-v /host/dir:/workspace) tem prioridade sobre o workspace padrão do disco de armazenamento — seu diretório do host é usado em seu lugar. - macOS: o binário deve ser assinado com entitlements do Hypervisor.framework (
com.apple.security.hypervisor). O release enviado está; um binário re-assinado ou recém-compilado o perde silenciosamente e toda inicialização de VM falha comkrun_start_enter returned: -22 (EINVAL). Re-assine-o (ad-hoc é suficiente):codesign --force --sign - --entitlements hv.entitlements <smolvm-bin>ondehv.entitlementsé um plist contendo<key>com.apple.security.hypervisor</key><true/>. --ssh-agentrequer um agente SSH em execução no host (SSH_AUTH_SOCKdeve estar definido).- A aceleração de GPU requer libkrun compilado com
GPU=1e virglrenderer + um driver Vulkan no host (veja Aceleração de GPU abaixo). - Windows:
--netfunciona da mesma forma que em outras plataformas (virtio-net com encaminhamento de porta de entrada; TSI para VMs somente de saída), assim comomachine exec/ sessões interativas emachine stats. Ainda não disponível no Windows: aceleração de GPU emachine fork/ snapshot. O create do pack precisa destorage-template.ext4/overlay-template.ext4ao lado desmolvm.exe(o Windows não temmkfs.ext4no host).
Aceleração de GPU
O smolvm expõe a GPU do host aos convidados via virtio-gpu / Venus (Vulkan-over-virtio). As cargas de trabalho convidadas veem um dispositivo Vulkan real; no Linux + Intel isso é renderizado como:
ANGLE (Intel, Vulkan 1.4 (Virtio-GPU Venus (Intel(R) UHD Graphics ...)), venus)
Requisitos do host
macOS — virglrenderer e MoltenVK estão incluídos na distribuição do smolvm. Nenhuma instalação extra é necessária.
Linux — virglrenderer e um driver Vulkan do host devem ser instalados a partir do gerenciador de pacotes do sistema:
| Distro | Pacotes |
|---|---|
| Alpine | apk add virglrenderer mesa-vulkan-intel (ou mesa-vulkan-ati para AMD) |
| Debian/Ubuntu | apt install virglrenderer0 mesa-vulkan-drivers |
O virglrenderer depende de libEGL e libdrm da pilha de drivers de GPU do host — estes são específicos de hardware e não podem ser incluídos. Qualquer host Linux com capacidade de GPU já os terá instalados via seu driver de GPU.
Uso
# CLI
smolvm machine run --gpu --image alpine -- vulkaninfo --summary
# Smolfile
# gpu = true
# gpu_vram = 2048 # MiB, padrão 4096
O carregador Vulkan do convidado deve ser apontado para o ICD virtio:
export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/virtio_icd.x86_64.json
Exemplo de navegador headless
Veja examples/headless-browser/ para uma configuração Chromium funcional usando ANGLE + Venus para WebGL acelerado por hardware dentro de uma VM headless.
Remoting de API CUDA
--gpu e --cuda fornecem interfaces diferentes. --gpu expõe Vulkan através de virtio-gpu / Venus; ele não fornece CUDA. --cuda habilita o remoting de API CUDA: shims convidados sem driver encaminham chamadas CUDA via vsock para um processo do host, que as executa através do driver NVIDIA do host.
O remoting CUDA requer uma GPU NVIDIA e um driver NVIDIA funcional no host. Não é passagem de GPU: o convidado não recebe nem o dispositivo físico nem um driver NVIDIA.
Hosts Linux com muitos forks devem usar um kernel contendo a correção KVM upstream
916b7f4.
Kernels afetados podem relatar intermitentemente ENOMEM no primeiro KVM_RUN mesmo
com memória abundante do host; o smolvm reduz a exposição e substitui um worker com falha,
mas a atualização do kernel é a correção definitiva.
A fronteira da VM ainda isola a CPU, a memória e o sistema de arquivos da carga de trabalho. O acesso à GPU é mediado por processos do host e pela GPU compartilhada do host, portanto o isolamento de GPU permanece em nível de processo, em vez de uma fronteira de hardware ou VM. Não trate o remoting CUDA como uma fronteira de isolamento de GPU multiusuário endurecida.
Veja Acesso à GPU por remoting de API: como uma microVM sem driver executa CUDA para o design, as compensações e a comparação com passagem.
Desenvolvimento
Veja docs/DEVELOPMENT.md.
Apache-2.0 · feito por @binsquare · twitter · github