Skip to main content
Use remote mode when you want centralized execution infrastructure and shared policy enforcement across multiple clients.

Diagram 1: Remote architecture overview

Start the server

isol8 serve \
  --key my-secret-key \
  --port 3000
If --key and ISOL8_API_KEY are both missing, startup fails. --key takes precedence when provided.
Port resolution order is --port > ISOL8_PORT > PORT > 3000. If the chosen port is unavailable, isol8 serve prompts for another port or can auto-select an open port.

Serve runtime behavior

isol8 serve has two startup paths:
  • Bun/dev path: runs server in-process.
  • Built CLI (Node) path: downloads/runs standalone isol8-server binary and can prompt for version update.
  • Both paths run graceful cleanup on SIGINT/SIGTERM (sessions, containers, and images).
Use isol8 serve --update to force binary re-download.

Authentication contract

  • GET /health: no auth required.
  • all other endpoints: require Authorization: Bearer <api-key>.
StatusMeaning
401Authorization header missing
403token provided but invalid

Where remote values are set

ConcernCLIConfigAPI bodyLibrary
Server listen/authisol8 serve --port --keyAPI key can come from env (ISOL8_API_KEY)n/an/a
Server defaultsn/adefaults.*, maxConcurrent, cleanup.*, security.*merged with request optionsn/a
Request overridesisol8 run --host --key ... flagsbaseline defaults onlyoptions in /execute bodynew RemoteIsol8(..., isol8Options)
Persistent sessionisol8 run --persistent --host ...cleanup policy affects idle sessionssessionIdRemoteIsol8Options.sessionId

Request envelope

Remote execution endpoints use this shape:
{
  "request": { "code": "print('ok')", "runtime": "python" },
  "options": { "timeoutMs": 30000 },
  "sessionId": "optional-session-id"
}
options are merged over server defaults for that request.

Execute remotely

curl -sS -X POST http://localhost:3000/execute \
  -H "Authorization: Bearer $ISOL8_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request": {
      "code": "print(2 ** 10)",
      "runtime": "python"
    }
  }'

Persistent sessions

A stable sessionId reuses one container across calls.
curl -sS -X POST http://localhost:3000/execute \
  -H "Authorization: Bearer $ISOL8_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "session-123",
    "request": { "code": "x = 41", "runtime": "python" }
  }'
Destroy session when done:
curl -X DELETE http://localhost:3000/session/session-123 \
  -H "Authorization: Bearer $ISOL8_API_KEY"
Idle persistent sessions remain until explicit delete or cleanup pruning (cleanup.autoPrune, cleanup.maxContainerAgeMs).

Auto-pruning setup (idle session cleanup)

The server runs a periodic cleanup loop when cleanup.autoPrune is enabled.
  • sweep interval: every 60_000 ms (60s)
  • idle threshold: cleanup.maxContainerAgeMs
  • active sessions are skipped while executing (isActive === true)
  • lastAccessedAt is refreshed on execute and file upload/download calls

Defaults

  • cleanup.autoPrune: true
  • cleanup.maxContainerAgeMs: 3_600_000 (1 hour)

Configure in isol8.config.json

{
  "cleanup": {
    "autoPrune": true,
    "maxContainerAgeMs": 1800000
  }
}
The example above prunes idle sessions after 30 minutes.

Practical tuning guidance

  • shorter idle timeout (5m to 30m): lower container footprint, more frequent cold session starts
  • longer idle timeout (1h to 24h): better session reuse, higher idle resource usage
  • disable auto-prune only if you have explicit lifecycle management (for example always calling DELETE /session/:id)
If users report disappearing sessions, check cleanup.maxContainerAgeMs first before investigating execution errors.

Streaming behavior

  • POST /execute/stream emits SSE events (stdout, stderr, exit, error).
  • current server implementation always uses ephemeral mode for streaming path.
Sending sessionId to /execute/stream does not create persistent streaming sessions in current implementation.

File APIs (persistent sessions only)

  • POST /file: upload base64 content to session container
  • GET /file?sessionId=...&path=...: download base64 content
curl -sS -X POST http://localhost:3000/file \
  -H "Authorization: Bearer $ISOL8_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "session-123",
    "path": "/sandbox/input.txt",
    "content": "aGVsbG8K"
  }'

Operations checklist

  • keep strict defaults in isol8.config.json (network: "none" by default)
  • size maxConcurrent to host capacity
  • configure cleanup pruning for session-heavy workloads
  • place TLS/rate limiting in front of the service
  • enable audit logging when provenance/compliance is required

FAQ

401 means missing Authorization header. 403 means token provided but it does not match server API key.
If a sessionId is configured, it calls DELETE /session/{id}. Without sessionId, there is no session to delete.
No. File upload/download are bound to a persistent session container.

Troubleshooting

  • Server start fails with API key error: pass --key or set ISOL8_API_KEY.
  • Session not found on file calls: create session first via /execute with the same sessionId.
  • Session state unexpectedly gone: check prune settings in cleanup.autoPrune and cleanup.maxContainerAgeMs.
  • Remote request hangs under load: inspect maxConcurrent queueing and host saturation.