Docker Sandbox
A sandbox is an isolated compute environment. Each sandbox has its own filesystem, network namespace, and configurable vCPU, memory, and disk. Sandboxes spin up in under 90ms and run any OCI-compatible image.
Sandbox types
Section titled “Sandbox types”| Type | Runtime value | Description |
|---|---|---|
| Docker | docker (default) | Standard runc-backed containers. Works on any node. |
| gVisor | gvisor | User-space kernel - intercepts syscalls. Better isolation, same hardware requirements. See gVisor Sandbox. |
| Firecracker | firecracker | Full microVM - each sandbox boots its own kernel in under 100ms. Requires bare-metal nodes. See Firecracker Sandbox. |
| GPU | docker + gpus field | Standard Docker with direct GPU passthrough. See GPU Sandbox. |
Lifecycle states
Section titled “Lifecycle states”created ──► running ──► stopped ──► running │ ▼ destroyed| State | Description |
|---|---|
running | Sandbox is up and accepting requests. |
stopped | Sandbox is paused; filesystem state is persisted. |
destroyed | Sandbox and all its data are permanently removed. |
Create
Section titled “Create”import { MicroVM } from '@aerol-ai/aerolvm-sdk'
const client = new MicroVM({ apiUrl: process.env.SB_API_URL, patToken: process.env.SB_PAT_TOKEN,})
const sandbox = await client.create({ image: 'ubuntu:22.04', cpu: 1, memoryMB: 1024, diskGB: 10, lifecycle: { stopIfIdleFor: 60 * 60 * 1_000_000_000, // 1 hour in nanoseconds destroyAtAge: 24 * 60 * 60 * 1_000_000_000, // 24 hours in nanoseconds },})
console.log(sandbox.id)console.log(sandbox.publicURL)console.log(sandbox.sshPrivateKey) // only returned by create()from microvm import MicroVM
client = MicroVM( api_url='https://sandbox.example.com', pat_token='your-token',)
sandbox = client.create({ 'image': 'ubuntu:22.04', 'cpu': 1.0, 'memoryMB': 1024, 'diskGB': 10, 'lifecycle': { 'stopIfIdleFor': 3_600_000_000_000, # 1 hour 'destroyAtAge': 86_400_000_000_000, # 24 hours },})
print(sandbox.id)print(sandbox.publicURL)print(sandbox.sshPrivateKey) # only returned by create()import ( "context" "fmt" "log" "os" "time"
microvm "github.com/aerol-ai/microvm/sdk/go/pkg/microvm" sdktypes "github.com/aerol-ai/microvm/sdk/go/pkg/types")
client, err := microvm.NewClientWithConfig(&sdktypes.MicroVMConfig{ APIUrl: os.Getenv("SB_API_URL"), PATToken: os.Getenv("SB_PAT_TOKEN"),})if err != nil { log.Fatal(err)}
sandbox, err := client.Create(context.Background(), sdktypes.CreateSandboxOptions{ Image: "ubuntu:22.04", CPU: 1, MemoryMB: 1024, DiskGB: 10, Lifecycle: &sdktypes.Lifecycle{ StopIfIdleFor: time.Hour, DestroyAtAge: 24 * time.Hour, },})if err != nil { log.Fatal(err)}
fmt.Println(sandbox.ID, sandbox.PublicURL)fmt.Println(sandbox.SSHPrivateKey) // only returned by Create()use aerolvm_sdk::{Client, CreateOptions, Lifecycle};
let client = Client::new( Some("https://sandbox.example.com"), Some("your-token"),)?;
let sandbox = client.create(CreateOptions { image: "ubuntu:22.04".to_string(), cpu: Some(1), memory_mb: Some(1024), disk_gb: Some(10), lifecycle: Some(Lifecycle { stop_if_idle_for: 3_600_000_000_000, destroy_at_age: 86_400_000_000_000, ..Default::default() }), ..Default::default()})?;
println!("{} {:?}", sandbox.data.id, sandbox.data.public_url);println!("{:?}", sandbox.ssh_private_key); // only returned by create()import ai.aerol.microvm.MicroVMClient;import ai.aerol.microvm.MicroVMConfig;import ai.aerol.microvm.Sandbox;import ai.aerol.microvm.model.CreateOptions;import ai.aerol.microvm.model.Lifecycle;
MicroVMClient client = new MicroVMClient( new MicroVMConfig() .setApiUrl("https://sandbox.example.com") .setPatToken(System.getenv("SB_PAT_TOKEN")));
Sandbox sandbox = client.create( new CreateOptions() .setImage("ubuntu:22.04") .setCpu(1.0) .setMemoryMb(1024) .setDiskGb(10) .setLifecycle(new Lifecycle() .setStopIfIdleFor(3_600_000_000_000L) .setDestroyAtAge(86_400_000_000_000L)));
System.out.println(sandbox.id + " " + sandbox.publicUrl);System.out.println(sandbox.sshPrivateKey); // only returned by create()Named sandboxes
Section titled “Named sandboxes”Pass a name field to pin a human-readable identifier to the sandbox. Names must be unique — if you call create with a name that belongs to an existing sandbox, the daemon returns HTTP 409 Conflict with "sandbox name already in use". Omit the field (or leave it empty) to let the daemon generate a random ID.
Connect to existing sandbox
Section titled “Connect to existing sandbox”Retrieve a running sandbox by ID to get a fully usable sandbox object.
const sandbox = await client.get('sbx_abc123')
console.log(sandbox.id)console.log(sandbox.publicURL)sandbox = client.get('sbx_abc123')
print(sandbox.id)print(sandbox.public_url)sandbox, err := client.Get(ctx, "sbx_abc123")if err != nil { log.Fatal(err)}
fmt.Println(sandbox.ID, sandbox.PublicURL)let sandbox = client.get("sbx_abc123")?;
println!("{} {:?}", sandbox.data.id, sandbox.data.public_url);Sandbox sandbox = client.get("sbx_abc123");
System.out.println(sandbox.id + " " + sandbox.publicUrl);Start and stop
Section titled “Start and stop”Stopping persists all container-level filesystem state. Starting resumes from the persisted layer - running processes are not retained across a stop/start cycle.
await sandbox.stop()await sandbox.start()sandbox.stop()sandbox.start()if err := sandbox.Stop(ctx); err != nil { log.Fatal(err) }if err := sandbox.Start(ctx); err != nil { log.Fatal(err) }sandbox.stop()?;sandbox.start()?;sandbox.stop();sandbox.start();Destroy
Section titled “Destroy”Permanently removes the sandbox, all its data, and its metadata. External storage mounts are unmounted before removal.
await sandbox.destroy()sandbox.destroy()if err := sandbox.Destroy(ctx); err != nil { log.Fatal(err) }sandbox.destroy()?;sandbox.destroy();Resize
Section titled “Resize”Change CPU or memory allocation on a running sandbox without restarting it.
await sandbox.resize({ cpu: 2, memoryMB: 2048 })sandbox.resize({'cpu': 2, 'memoryMB': 2048})err := sandbox.Resize(ctx, sdktypes.ResizeOptions{CPU: 2, MemoryMB: 2048})sandbox.resize(aerolvm_sdk::ResizeOptions { cpu: Some(2), memory_mb: Some(2048) })?;sandbox.resize(new ResizeOptions().setCpu(2.0).setMemoryMb(2048));List and get
Section titled “List and get”const sandboxes = await client.list()const sandbox = await client.get(id)sandboxes = client.list()sandbox = client.get(sandbox_id)sandboxes, err := client.List(ctx)sandbox, err := client.Get(ctx, id)let sandboxes = client.list()?;let sandbox = client.get(&id)?;var sandboxes = client.list();var sandbox = client.get(id);Idle lifecycle
Section titled “Idle lifecycle”Sandboxes can self-terminate based on age or inactivity. Lifecycle parameters can be updated at any time without restarting the sandbox.
await sandbox.updateLifecycle({ stopIfIdleFor: 2 * 60 * 60 * 1_000_000_000, // 2 hours destroyAtAge: 48 * 60 * 60 * 1_000_000_000, // 48 hours})sandbox.update_lifecycle({ 'stopIfIdleFor': 7_200_000_000_000, 'destroyAtAge': 172_800_000_000_000,})err := sandbox.UpdateLifecycle(ctx, sdktypes.Lifecycle{ StopIfIdleFor: 2 * time.Hour, DestroyAtAge: 48 * time.Hour,})sandbox.update_lifecycle(aerolvm_sdk::Lifecycle { stop_if_idle_for: 7_200_000_000_000, destroy_at_age: 172_800_000_000_000, ..Default::default()})?;sandbox.updateLifecycle( new Lifecycle() .setStopIfIdleFor(7_200_000_000_000L) .setDestroyAtAge(172_800_000_000_000L));See Environment for image selection, environment variables, and resource defaults.