Custom sandbox images (BYO)
Sagewai ships seven pre-built sandbox variants (base, general, ml, ops,
erp, ecommerce, api) at ghcr.io/sagewai/sandbox-<variant>. When you
need tooling we don't ship — a specific CLI, a private wheel, a GPU runtime,
or just a smaller/larger base — you can bake your own image and point
sagewai worker start --sandbox-image at it.
This page covers the hard constraints your image must meet, a copy-paste template, and the validation step.
Requirements
Your image MUST:
- Include
sagewai-tool-runnerin a version that satisfies this SDK'sTOOL_RUNNER_VERSION_SPEC(currently>=0.1,<0.2). The binary must be onPATHassagewai-tool-runner. - Have
tini(or equivalent) as PID 1, with a long-lived command so the container stays alive.ENTRYPOINT ["/usr/bin/tini", "--"]+CMD ["sleep", "infinity"]works. - Default
WORKDIRto/workspace, and leave it writable by therootuser (Sagewai mounts the scratch dir here).
Your image SHOULD:
- Inherit from
ghcr.io/sagewai/sandbox-base:<your-sdk-version>— this covers points 1-3 for you. - Keep root filesystem read-only at runtime (Sagewai sets this already,
so avoid writing to
/etc,/usr, etc. during execution). - Declare all added tools in the image's
README.mdso operators know what's available.
Template
# syntax=docker/dockerfile:1.7
# Pin the exact SDK version whose worker will schedule against this image.
FROM ghcr.io/sagewai/sandbox-base:0.1.5 AS runner
USER root
# Example: add your internal CLI.
RUN curl -fsSL -o /tmp/mycli.tar.gz \
"https://example.com/mycli-1.0.0-linux-amd64.tar.gz" \
&& echo "<sha256> /tmp/mycli.tar.gz" | sha256sum -c \
&& tar -xzf /tmp/mycli.tar.gz -C /usr/local/bin \
&& rm /tmp/mycli.tar.gz
# Example: add a private pip package with hash pinning.
COPY requirements-internal.txt /tmp/
RUN pip install --no-cache-dir --require-hashes -r /tmp/requirements-internal.txt \
&& rm /tmp/requirements-internal.txt
# Don't overwrite ENTRYPOINT or CMD — base's config is what tool-runner needs.
Validate before shipping
Always run sagewai sandbox validate before wiring a new image into a
project. It pulls the image, probes the runner, and confirms the sandbox
lifecycle works end-to-end:
sagewai sandbox validate ghcr.io/your-org/your-sandbox:1.0
A passing image prints six ✓ lines:
✓ image pulled (digest sha256:...)
✓ container starts
✓ sagewai-tool-runner --version → 0.1.0 (compatible)
✓ bash echo round-trip → 42 ms
✓ /workspace writable
✓ env scrub: HOST_SECRET not visible
PASS — image is compatible with this SDK
Failures exit non-zero with a specific remediation. The most common error
— sagewai-tool-runner not found in PATH — usually means you stripped
/usr/local/bin from your image; re-inherit from sandbox-base and
retry.
Pointing workers at a custom image
Two ways:
# Worker-default (applies to every run this worker claims)
sagewai worker start --sandbox-image ghcr.io/your-org/your-sandbox:1.0 …
# Agent-scoped (just this one agent)
# In your agent spec YAML: sandbox_image: ghcr.io/your-org/your-sandbox:1.0
Custom images skip SDK-level digest verification (they're not in the
manifest). Sagewai logs a single INFO line with the resolved digest on
first use so auditors can reconstruct what actually ran. Run
sagewai sandbox validate as your trust anchor.
Reclaim some size
The general variant carries ~900 MB (Playwright + chromium dominate).
If you don't need browser automation, inherit from base directly and
add only what your agents need. A minimal web-scraping image can come in
at ~300 MB.