Skip to main content
Deploy isol8 as a centralized code execution service that multiple clients can share. This is useful for teams, platforms, and microservice architectures where code execution needs to be offloaded to a dedicated server.

Server Setup

Start the isol8 HTTP server:
# Basic server (requires Bun runtime)
isol8 serve --port 3000 --key my-secret-api-key

# With custom config
isol8 serve --port 3000 --key my-secret-api-key --config ./isol8.config.json
Or programmatically:
import { serve } from "isol8/server";

serve({
  port: 3000,
  apiKey: process.env.ISOL8_API_KEY!,
});

Remote Client (Library)

Connect to a remote isol8 server from any TypeScript/JavaScript application:
import { RemoteIsol8 } from "isol8";

const isol8 = new RemoteIsol8(
  {
    host: "http://execution-server:3000",
    apiKey: "my-secret-api-key",
  },
  {
    network: "none",
    memoryLimit: "512m",
  }
);

await isol8.start();   // Verifies server health via GET /health

const result = await isol8.execute({
  code: 'print("Hello from remote!")',
  runtime: "python",
});

console.log(result.stdout); // "Hello from remote!"

await isol8.stop();

Remote Client (CLI)

Execute code on a remote server from the command line:
# Set API key via environment variable
export ISOL8_API_KEY=my-secret-api-key

# Run code remotely
isol8 run -e "print('hello')" --runtime python --host http://server:3000

# Run a local file remotely
isol8 run script.py --host http://server:3000

# Remote persistent session
isol8 run --persistent -e "x = 42" --runtime python --host http://server:3000

Remote Persistent Sessions

Use persistent sessions on the server for multi-step workflows:
const isol8 = new RemoteIsol8(
  {
    host: "http://server:3000",
    apiKey: "my-api-key",
    sessionId: "user-123-session",  // Unique session ID
  },
  { network: "none" }
);

await isol8.start();

// First execution — creates the session
await isol8.execute({
  code: `
x = 42
with open("/sandbox/state.txt", "w") as f:
    f.write(str(x))
print("State saved")
`,
  runtime: "python",
});

// Second execution — reuses the same container
const result = await isol8.execute({
  code: `
with open("/sandbox/state.txt") as f:
    x = int(f.read())
print(f"State restored: x = {x}")
`,
  runtime: "python",
});

console.log(result.stdout); // "State restored: x = 42"

// Clean up the session
await isol8.stop(); // Sends DELETE /session/user-123-session

Streaming Over HTTP (SSE)

Stream execution output in real time via Server-Sent Events:
// Using the RemoteIsol8 client
for await (const event of isol8.executeStream({
  code: `
import time
for i in range(5):
    print(f"Step {i+1}/5")
    time.sleep(1)
print("Done!")
`,
  runtime: "python",
})) {
  switch (event.type) {
    case "stdout":
      process.stdout.write(event.data);
      break;
    case "stderr":
      process.stderr.write(event.data);
      break;
    case "exit":
      console.log(`\nExit code: ${event.data}`);
      break;
  }
}
Or using raw HTTP:
curl -N -X POST http://server:3000/execute/stream \
  -H "Authorization: Bearer my-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "for i in range(5): print(i)",
    "runtime": "python"
  }'
# data: {"type":"stdout","data":"0\n"}
# data: {"type":"stdout","data":"1\n"}
# ...
# data: {"type":"exit","data":"0"}

File Transfer (Remote)

Upload and download files on a remote persistent session:
// Upload a file
await isol8.putFile("/sandbox/input.csv", "name,score\nAlice,95\nBob,87");

// Execute code that uses the file
await isol8.execute({
  code: `
import csv
with open("/sandbox/input.csv") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['name']}: {row['score']}")
`,
  runtime: "python",
});

// Download a result file
const output = await isol8.getFile("/sandbox/output.txt");
console.log(output.toString());

Server Configuration

Configure the server via isol8.config.json:
{
  "maxConcurrent": 20,
  "defaults": {
    "timeoutMs": 30000,
    "memoryLimit": "512m",
    "network": "none"
  },
  "cleanup": {
    "autoPrune": true,
    "maxContainerAgeMs": 3600000
  }
}
Key server-specific settings:
SettingDefaultDescription
maxConcurrent10Maximum parallel executions
cleanup.autoPrunetruePeriodically remove idle sessions
cleanup.maxContainerAgeMs3600000Max session age before pruning (1 hour)

Multi-Tenant Architecture

Serve multiple users with isolated sessions:
import { Hono } from "hono";
import { DockerIsol8 } from "isol8";

const app = new Hono();

// One engine per tenant (or a shared engine with session IDs)
const engines = new Map<string, DockerIsol8>();

app.post("/execute/:userId", async (c) => {
  const userId = c.req.param("userId");

  // Get or create engine for this user
  if (!engines.has(userId)) {
    const engine = new DockerIsol8({
      mode: "persistent",
      network: "none",
      memoryLimit: "256m",
    });
    await engine.start();
    engines.set(userId, engine);
  }

  const engine = engines.get(userId)!;
  const { code, runtime } = await c.req.json();

  const result = await engine.execute({ code, runtime });
  return c.json({
    stdout: result.stdout,
    stderr: result.stderr,
    exitCode: result.exitCode,
  });
});

// Cleanup inactive sessions periodically
setInterval(async () => {
  // Application-level cleanup logic
  for (const [userId, engine] of engines) {
    // Add your own inactivity tracking
    await engine.stop();
    engines.delete(userId);
  }
}, 3600000);

export default app;

Health Monitoring

Check server health programmatically:
# Health check
curl http://server:3000/health
# {"status": "ok"}
// In a monitoring script
const health = await fetch("http://server:3000/health");
if (!health.ok) {
  console.error("isol8 server is down!");
  // Alert your team
}