Retour aux mises à jour
New releaseAug 5, 2026

vpod v0.6.0

Sandbox Linux légères et sécurisées pour les processus non fiables. Fonctionne dans le navigateur et sur le serveur.

Partager

Vpod

Qu'est-ce qu'un vpod ?

Un vpod est un sandbox léger et portable qui offre à un processus non fiable un environnement Linux instantané. Il utilise une architecture RISC‑V et s'exécute entièrement dans WebAssembly.

  • Démarrage rapide : Démarre en moins d'une seconde.
  • Portable : Fonctionne partout sans aucune configuration requise.
  • Isolé : Tout l'état d'exécution reste dans les sandboxes WASM.

Comment ça fonctionne

Un vpod exécute un système RISC‑V complet (RV64GC, un seul vCPU) compilé en WebAssembly. À l'intérieur, il démarre un vrai noyau Linux avec un véritable espace utilisateur, de sorte que les shells, outils et démons se comportent comme sur du matériel réel.

Instantanés. Au lieu de démarrer Linux à partir de zéro, un vpod restaure un instantané : un état machine sauvegardé (registres CPU, RAM, système de fichiers) capturé juste après le démarrage. Sa restauration prend bien moins d'une seconde. La suspension fonctionne de la même manière en sens inverse : seules les pages mémoire modifiées sont réécrites sur le disque, ce qui permet de mettre un sandbox en pause et de le reprendre plus tard, même depuis un autre processus.

Traduction à l'avance. L'émulation pure instruction par instruction est lente, et WebAssembly exclut un JIT à l'exécution. Ainsi, lors de la construction de l'instantané, les chemins de code invité les plus sollicités sont traduits du RISC‑V en code natif compilé dans le module WASM lui-même. À l'exécution, l'émulateur bascule vers ces blocs traduits lorsque le code invité correspond, et revient à l'interpréteur dans le cas contraire. Cela représente environ 5x de gain sur les tâches gourmandes en CPU, sans aucun effet sur l'isolation : le code traduit passe par les mêmes contrôles MMU et mémoire que le code interprété.

La frontière WASI. Le composant WASM communique avec l'hôte exclusivement via WASI 0.2. L'invité ne voit jamais les descripteurs de fichiers, sockets ou mémoire de l'hôte : l'accès au système de fichiers passe par des répertoires explicitement montés, et la mise en réseau passe par une pile réseau en mode utilisateur à l'intérieur du composant qui ne demande jamais à l'hôte que des sockets sortantes simples. Tout le reste (noyau invité, processus, mémoire) vit dans la mémoire linéaire WASM et meurt avec elle.

Spécification RV64GC

G (Extensions à usage général)

  • I : Jeu d'instructions entier de base 64 bits.
  • M : Multiplication et division matérielles, utiles pour le hachage et la cryptographie.
  • A : Opérations atomiques pour les programmes thread-safe.
  • F/D : Virgule flottante simple et double précision, adaptée au calcul scientifique et à l'inférence ML.

C (Instructions compressées) Réduit la taille du code de 30 %, améliorant la vitesse de récupération des instructions et l'efficacité mémoire. Cela compte lors de l'exécution d'un espace utilisateur Linux complet dans notre environnement WASM à mémoire contrainte.

[!NOTE] L'extension V (vectorielle) n'est pas implémentée. Les instructions RVV s'exécuteraient comme du RISC-V émulé ; il n'y a pas de passage SIMD vers le CPU hôte. L'ajout de V augmenterait la surcharge d'émulation sans aucun bénéfice de performance pour les charges vectorisées.

Pour commencer

SDK TypeScript

npm install @capsule-run/vpod
import { Sandbox } from "@capsule-run/vpod";

const sandbox = await Sandbox.create();

// L'état est préservé entre les appels
await sandbox.commands.run("export API_KEY=secret");
const key = await sandbox.commands.run("echo $API_KEY");
console.log(key.stdout); // secret

// REPL Python — les variables persistent
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();

Le même paquet fonctionne dans un onglet de navigateur, où l'instantané est mis en cache dans le stockage privé d'origine plutôt que sur le disque.

[!IMPORTANT] Le premier appel à Sandbox.create() télécharge l'instantané par défaut (alpine) et le met en cache localement s'il n'est pas déjà présent.

SDK Python

pip install vpod
from vpod import Sandbox

# Exécuter une commande
sandbox = Sandbox.create()
result = sandbox.commands.run("whoami")
print(result.stdout)  # root
sandbox.close()

# Session persistante — l'état est préservé entre les appels
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 — les variables persistent
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 installer via PowerShell (Windows)
irm https://install.vpod.sh | iex
# Récupérer un instantané
vpod pull alpine:latest

# Démarrer un shell interactif
vpod

Documentation

Consultez la documentation Vpod.

Limitations

  • Surcharge d'émulation : Il n'y a pas de virtualisation matérielle dans WebAssembly, donc tout le code invité est émulé. La surcharge dépend entièrement de la charge de travail : les tâches liées aux E/S et au réseau s'exécutent presque à la vitesse native, tandis que les tâches lourdes en CPU s'exécutent nettement plus lentement même avec la traduction AOT. Si votre charge de travail consiste principalement à « exécuter un outil, lire un fichier, appeler une API », vous ne remarquerez rien.
  • Pas d'accès GPU : CUDA, Metal et les accélérateurs ML matériels ne sont pas disponibles. Un support pourrait être ajouté à l'avenir avec wasi-nn.

Contribuer

Les contributions sont les bienvenues, des rapports de bugs au support de nouveaux périphériques. Ouvrez une issue pour discuter de tout élément substantiel avant de le construire.

Prérequis

  • Rust (dernière version stable) avec la cible wasm32-wasip2 : rustup target add wasm32-wasip2
  • Python 3.10+ pour le SDK Python
  • Node 20+ pour le SDK TypeScript
  • Zig (0.16) et bsdtar, nécessaires uniquement si vous construisez vous-même des instantanés

Configuration de développement

# Ponctuel : générer le stub AOT (un nouveau clone n'a pas de blocs traduits)
./scripts/aot-stub.sh

# Construire le composant WASM (bibliothèque + CLI). Copie les deux niveaux dans sdks/python/vpod/
./scripts/build-wasm.sh

# Installer la CLI hôte
cargo install --path crates/vpod

# Installer le SDK Python en mode développement
pip install -e "sdks/python[dev]"

# Construire le SDK TypeScript. Récupère le composant depuis le répertoire du SDK Python
cd sdks/typescript && npm install && npm run build

Catégories