
vpod v0.6.0
Sandboxes Linux leves e seguros para processos não confiáveis. Funciona no navegador e no servidor.
Vpod
O que é um vpod?
Um vpod é um sandbox leve e portátil que dá a um processo não confiável um ambiente Linux instantâneo. Ele usa uma arquitetura RISC‑V e roda inteiramente dentro do WebAssembly.
- Inicialização rápida: Inicializa em menos de um segundo.
- Portátil: Roda em qualquer lugar sem necessidade de configuração.
- Isolado: Todo o estado de execução permanece dentro dos sandboxes WASM.
Como funciona
Um vpod executa um sistema RISC‑V completo (RV64GC, uma única vCPU) compilado para WebAssembly. Dentro dele, um kernel Linux real é inicializado com um userspace real, então shells, ferramentas e daemons se comportam como fariam em hardware real.
Snapshots. Em vez de inicializar o Linux do zero, um vpod restaura um snapshot: um estado de máquina salvo (registradores da CPU, RAM, sistema de arquivos) capturado logo após a inicialização. Restaurar um leva bem menos de um segundo. A suspensão funciona da mesma forma, ao contrário: apenas as páginas de memória sujas são gravadas de volta no disco, então você pode pausar um sandbox e retomá-lo depois, até mesmo de outro processo.
Tradução ahead-of-time. A emulação pura instrução por instrução é lenta, e o WebAssembly descarta um JIT em tempo de execução. Então, no momento da construção do snapshot, os caminhos de código convidado mais quentes são traduzidos de RISC‑V para código nativo que é compilado no próprio módulo WASM. Em tempo de execução, o emulador despacha para esses blocos traduzidos quando o código convidado corresponde, e recorre ao interpretador quando não corresponde. Isso vale aproximadamente 5x em trabalho limitado por CPU, com efeito zero no isolamento: o código traduzido passa pelas mesmas verificações de MMU e memória que o código interpretado.
A fronteira WASI. O componente WASM fala com o host exclusivamente através do WASI 0.2. O convidado nunca vê descritores de arquivo, sockets ou memória do host: o acesso ao sistema de arquivos passa por diretórios explicitamente montados, e a rede passa por uma pilha de rede em modo de usuário dentro do componente que só pede ao host sockets de saída simples. Todo o resto (kernel convidado, processos, memória) vive dentro da memória linear do WASM e morre com ela.
Especificação RV64GC
G (Extensões de propósito geral)
- I: Conjunto de instruções inteiras de 64 bits base.
- M: Multiplicação e divisão por hardware, útil para hashing e criptografia.
- A: Operações atômicas para programas thread-safe.
- F/D: Ponto flutuante de precisão simples e dupla, adequado para computação científica e inferência de ML.
C (Instruções compactas) Reduz o tamanho do código em 30%, melhorando a velocidade de busca de instruções e a eficiência de memória. Isso importa ao executar um userspace Linux completo dentro do nosso ambiente WASM com restrição de memória.
[!NOTE] A extensão V (vetorial) não é implementada. Instruções RVV seriam executadas como RISC-V emulado; não há passagem SIMD para a CPU do host. Adicionar V aumentaria a sobrecarga de emulação sem nenhum benefício de desempenho para cargas de trabalho vetorizadas.
Começando
SDK TypeScript
npm install @capsule-run/vpod
import { Sandbox } from "@capsule-run/vpod";
const sandbox = await Sandbox.create();
// O estado é preservado entre chamadas
await sandbox.commands.run("export API_KEY=secret");
const key = await sandbox.commands.run("echo $API_KEY");
console.log(key.stdout); // secret
// REPL Python — variáveis persistem
await sandbox.code.run("data = [1, 2, 3]");
const total = await sandbox.code.run("print(sum(data))");
console.log(total.text); // 6
await sandbox.close();
O mesmo pacote roda em uma aba do navegador, onde o snapshot é armazenado em cache no armazenamento privado de origem em vez de no disco.
[!IMPORTANT] A primeira chamada a
Sandbox.create()baixa o snapshot padrão (alpine) e o armazena em cache localmente se ainda não estiver presente.
SDK Python
pip install vpod
from vpod import Sandbox
# Executar um comando
sandbox = Sandbox.create()
result = sandbox.commands.run("whoami")
print(result.stdout) # root
sandbox.close()
# Sessão persistente — estado preservado entre chamadas
with Sandbox.create() as sandbox:
sandbox.commands.run("export API_KEY=secret")
result = sandbox.commands.run("echo $API_KEY")
print(result.stdout) # secret
# REPL Python — variáveis persistem
with Sandbox.create() as sandbox:
sandbox.code.run("import requests")
sandbox.code.run("data = [1, 2, 3]")
result = sandbox.code.run("print(sum(data))")
print(result.text) # 6
CLI
curl -fsSL https://install.vpod.sh | sh
Ou instale via PowerShell (windows)
irm https://install.vpod.sh | iex
# Baixar um snapshot
vpod pull alpine:latest
# Iniciar um shell interativo
vpod
Documentação
Visite a documentação do Vpod.
Limitações
- Sobrecarga de emulação: Não há virtualização de hardware dentro do WebAssembly, então todo o código convidado é emulado. A sobrecarga depende inteiramente da carga de trabalho: trabalho limitado por I/O e por rede roda perto da velocidade nativa, enquanto trabalho pesado limitado por CPU roda visivelmente mais lento mesmo com tradução AOT. Se sua carga de trabalho é principalmente "executar uma ferramenta, ler um arquivo, chamar uma API", você não notará.
- Sem acesso a GPU: CUDA, Metal e aceleradores de ML por hardware não estão disponíveis. O suporte pode ser adicionado no futuro com wasi-nn.
Contribuindo
Contribuições são bem-vindas, desde relatórios de bugs até suporte a novos dispositivos. Abra uma issue para discutir qualquer coisa substancial antes de construí-la.
Pré-requisitos
- Rust (última versão estável) com o alvo
wasm32-wasip2:rustup target add wasm32-wasip2 - Python 3.10+ para o SDK Python
- Node 20+ para o SDK TypeScript
- Zig (0.16) e bsdtar, necessários apenas se você construir snapshots você mesmo
Configuração de desenvolvimento
# Única vez: gerar o stub AOT (um clone novo não tem blocos traduzidos)
./scripts/aot-stub.sh
# Construir o componente WASM (biblioteca + CLI). Copia ambas as camadas para sdks/python/vpod/
./scripts/build-wasm.sh
# Instalar o CLI do host
cargo install --path crates/vpod
# Instalar o SDK Python em modo de desenvolvimento
pip install -e "sdks/python[dev]"
# Construir o SDK TypeScript. Pega o componente do diretório do SDK Python
cd sdks/typescript && npm install && npm run build
npm run build usa como padrão --tier aot; o CI fixa --tier base. A construção
recusa um componente mais antigo que o arquivo mais recente em crates/, então execute novamente
./scripts/build-wasm.sh após tocar no emulador. Uma alteração no emulador só
aparece através do convidado, então um componente desatualizado compila e passa em quase
tudo.