microsandbox, on your own cloud today

Isolated sandboxes on your own cloud

Cellar is how you run the open-source microsandbox runtime on your own cloud today — a laptop, a rack, or VMs on AWS or GCP. Same hardware-isolated environments, without waiting on someone else's cloud.

curl -fsSL https://cellar.prodioslabs.in/install.sh | bash

Cluster

Start a cluster. Add machines when you need them.

Bootstrap a manager, join more nodes, and create sandboxes. Cellar keeps cluster state in Raft, then places hardware-isolated VMs on workers that are ready. You don't write YAML for this.

cellar · multi-node
# manager-a
$  
  1. 1cellar init stands up the first manager — Raft leader and cluster CA
  2. 2Mint a join-token, then cellar join to add more managers and workers
  3. 3sandbox create puts a microsandbox VM on a live node

Gateway

Open the HTTP front door. Mint a key.

Apps talk to cellar-gateway over HTTP, not the unix-socket CLI. Create a key on the Raft leader with cellar api-key create. The gateway loads the cluster CA from --data-dir, dials manager SandboxAPI, and authenticates callers with Authorization: Bearer cellar_….

cellar · gateway
# manager-a
$  
  1. 1Confirm the leader with cellar status, then mint a key with api-key create
  2. 2Start cellar-gateway on :8080 — it loads the cluster CA and reaches a manager
  3. 3Probe /healthz and /readyz, then call the HTTP API with Bearer cellar_…

Clients

Use the microsandbox SDKs you already know

Once the cluster is up, point the official microsandbox SDKs at your cellar-gatewayin cloud mode, pass a Cellar API key, and you're talking to sandboxes you run yourself. There's no separate Cellar SDK — you use theirs.

client.ts
import { Sandbox, setDefaultBackend } from "microsandbox";setDefaultBackend({  kind: "cloud",  url: "https://cellar.example.com",  apiKey: process.env.MSB_API_KEY!,});const sandbox = await Sandbox.builder("hello")  .image("python")  .create();const output = await sandbox.exec("python", ["-c", "print('hello from cellar')"]);console.log(output.stdout());
main.rs
use microsandbox::{set_default_backend, CloudBackend, Sandbox};#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {    set_default_backend(CloudBackend::new(        "https://cellar.example.com",        std::env::var("MSB_API_KEY")?,    )?);    let sandbox = Sandbox::builder("hello")        .image("python")        .create()        .await?;    let output = sandbox        .exec("python", ["-c", "print('hello from cellar')"])        .await?;    println!("{}", output.stdout()?);    sandbox.stop().await?;    Ok(())}
main.py
import asyncioimport osfrom microsandbox import BackendKind, Sandbox, set_default_backendset_default_backend(    BackendKind.CLOUD,    url="https://cellar.example.com",    api_key=os.environ["MSB_API_KEY"],)async def main():    sandbox = await Sandbox.create("hello", image="python")    output = await sandbox.exec("python", ["-c", "print('hello from cellar')"])    print(output.stdout_text)    await sandbox.stop()asyncio.run(main())
main.rb
require "microsandbox"Microsandbox.use_cloud_backend!(  ENV.fetch("MSB_API_KEY"),  url: "https://cellar.example.com",)Microsandbox::Sandbox.with("hello", image: "python") do |sandbox|  output = sandbox.exec("python", ["-c", "print('hello from cellar')"])  puts output.stdoutend
Configure microsandbox backends
# Point the official microsandbox CLI / SDKs at cellar-gateway.# Same cloud-mode surface as microsandbox cloud — your cluster, your key.export MSB_BACKEND=cloudexport MSB_API_URL=https://cellar.example.comexport MSB_API_KEY=cellar_…   # from: cellar api-key create --name appmsb contextmsb run python -- python -V