Skip to content

Start a supervised process in a running sandbox.

sandbox.run(command: string | string[], options?: RunOptions): Promise<Process>

Examples

const api = await sandbox.run("python -m http.server", { name: "api" });
const db = await sandbox.run(["pg_ctlcluster", "16", "main", "start", "--foreground"], {
name: "db",
restart: { policy: "on-failure", retries: 5 },
});
const once = await sandbox.run("python script.py", { restart: { policy: "no" } });

Arguments

Argument Description
command a string runs under /bin/sh -c; an array or list runs as it is, with no shell

Options

TypeScript Python Description
name name process name; the base name of the program by default
env env variables added to the sandbox’s environment for this process
workdir workdir working directory
user user user name or uid in the sandbox
restart restart when the process starts again: { policy, retries, backoff }, or Restart(policy, retries=0, backoff=0)

The call returns as soon as the process runs. When a process exits, its sandbox stays running, so you can still run commands in it. Use sandbox.stop or sandbox.remove to end the sandbox.

Restarts

  • policy is no, on-failure (after a non-zero exit code or a signal), always (after any exit, and whenever the sandbox starts) or unless-stopped, the default.
  • unless-stopped is like always until process.kill ends the process. A daemon restart leaves it down in a sandbox that stop stopped.
  • retries caps how many times in a row on-failure starts the process again. 0 or no value means no cap.
  • backoff is the first wait in seconds, 1 by default or when 0. Each later wait doubles, up to 60 seconds.

Names

Use up to 32 lowercase letters, digits, ., _ and -. A sandbox runs up to 16 processes. A run of a running name raises ConflictError with the code name_taken, and a run of an ended name replaces it.

Wait until the process ends and its restart policy will not start it again.

process.wait(options?: { signal?: AbortSignal }): Promise<ProcessInfo>

Examples

const info = await once.wait();
console.log(info.status.state, info.status.exit);

Options

TypeScript Python Description
signal an AbortSignal that ends the wait with the signal’s reason
timeout seconds to wait before raising the built-in TimeoutError

Ending the wait never ends the process.

Stop the process and cancel its restarts.

process.kill(options?: { force?: boolean }): Promise<ProcessInfo>

Examples

await api.kill();
await api.kill({ force: true });

Options

TypeScript Python Description
force force send KILL instead of TERM

The sandbox keeps running.

Return the output of every run of the process.

process.logs(): Promise<string>

Examples

console.log(await api.logs());

The daemon keeps a bounded log, so for a long run it may hold only the end.

Stream the log from its start, then new output as it arrives.

process.followLogs(options?: { signal?: AbortSignal }): AsyncGenerator<Uint8Array>

Examples

for await (const chunk of api.followLogs()) process.stdout.write(chunk);

The stream ends when the process ends or the sandbox stops. In TypeScript, an abort ends it with the signal’s reason. In Python, closing it ends it, and AsyncShard iterates it with async for.

Read the process’s record from the daemon.

process.inspect(): Promise<ProcessInfo>

Examples

const { status } = await api.inspect();
console.log(status.state, status.restarts);

A ProcessInfo holds name, command, env, workdir, user, restart, killed, and a status with state, restarts, exit and the start time. state is running, restarting, exited, killed, gave-up or stopped. process.info holds the record that the last call on that handle returned.

List the processes of a sandbox, in the order they were first run.

sandbox.processes.list(): Promise<ProcessInfo[]>

Examples

for (const info of await sandbox.processes.list()) console.log(info.name, info.status.state);

The list includes the processes any client ran.

Find a process by name and return a handle to it.

sandbox.processes.get(name: string): Promise<Process>

Examples

const api = await sandbox.processes.get("api");

For a server that keeps running, see Run a long-running server.