Skip to main content
A setup script is a bash script that runs inside the sandbox container before your main code executes. There are two independent levels: When both are present, the image-level script always runs first, then the request-level script.

Image-level setup scripts

Declare setupScript inside a prebuiltImages entry to bake recurring setup into a custom Docker image. The script is written to /sandbox/.isol8-setup.sh inside the image and executed automatically before every execution against that image. Use this for setup that is constant across executions: git identity, SSH configuration, tool symlinks, shell aliases, or any one-time environment preparation.
isol8.config.json
Build the image (once, or on every deploy — isol8 skips unchanged images):
Or pass the script inline when building from the CLI:

Content-addressed caching

isol8 hashes runtime + packages + setupScript to produce a deps hash stored as a Docker image label. If neither the packages nor the script has changed, isol8 setup skips the build entirely. Changing a single character in the script invalidates the hash and triggers a rebuild.

Multi-line scripts

Supply a multi-line script using a JSON string with \n, or use a separate shell file with --setup ./setup.sh in the CLI:
isol8.config.json

Request-level setup scripts

Pass setupScript directly in an ExecutionRequest to run ad-hoc setup on the container before your code. This is useful for tasks that differ per execution: cloning a specific repo, writing config files, setting environment variables from secrets, or installing a package not in the base image.

Execution environment

Both image-level and request-level scripts run with the same constraints:
  • User: sandbox (uid 100, non-root)
  • Working directory: /sandbox
  • Shell: bash
  • Timeout: subject to the same timeoutMs as the full execution request
  • Exit code: a non-zero exit from the setup script aborts the execution before the main code runs (see Error handling below)
  • Secrets: values from the engine’s secrets option are available as environment variables and are automatically masked in stdout/stderr

Execution order

When both levels are set, the order is deterministic:
If any stage exits non-zero, the remaining stages do not run. In streaming mode, StreamEvent objects with phase: "setup" are emitted during stages 1–2, and phase: "code" during stage 3.

Common patterns

Git identity for agent runs

Bake git identity into the image so every agent step can commit without extra setup:

Clone a private repo before execution

Use a request-level script to clone a specific branch per task:

Configure package registries

Point npm or pip to a private registry for every execution against a custom image:

Install a non-standard tool

Use a request-level script to install a tool that isn’t in the base image:
For tools needed on every run, always prefer baking them into a custom image via prebuiltImages[].setupScript or installPackages. Request-level installs run on every call and add latency.

Write config files before agent runs

Inject .npmrc, .gitconfig, or other config files before the agent starts:

Warm up a persistent session

In persistent mode, run setup once at the start of the session rather than on every request:

Error handling

Non-streaming (execute)

If the setup script exits non-zero, execute() throws before running your code:
Always check that secrets (tokens, passwords) are available before running scripts that depend on them:

Streaming (executeStream)

When using executeStream, setup-script output is yielded as StreamEvent objects with phase: "setup" before any phase: "code" events appear. If the script exits non-zero, the stream emits a { type: "error", phase: "setup" } event followed by the exit event, and the main code never runs — no further events are yielded.
The phase field is optional on StreamEvent for backward compatibility, but is always set by isol8 — setup events always carry "setup" and main code events always carry "code". Checking event.phase === "setup" is safe.

Custom images

Bake packages and setup scripts into reusable Docker images with prebuiltImages.

Persistent execution

Reuse a single container across multiple execute() calls to preserve workspace state.

Agent in a Box

Run the pi coding agent inside isol8 — setup scripts prepare the workspace before the agent starts.

One-shot coding agents

Architecture and pipeline: clone repo, implement, verify, fix, and open a PR — setup scripts handle context hydration.

Execution guide

Streaming output, execution modes, resource limits, and file I/O.