Configuration

Custom sandboxes

Give the agents the toolchain your repository needs, at the size it needs, before a mission starts.

Overview

Each agent runs in a sandbox, which is an isolated container with Node, pnpm, git and the agent CLIs already installed. This setup is the platform base. A repository that also needs Python, a JDK, Go, a system library or a private package registry gets a custom sandbox. A custom sandbox is a set of steps that run on top of the platform base. SHIP builds it once, and every mission reuses it.

A build runs your steps, checks them and keeps a snapshot of the result. Missions start from that snapshot, so the tools are ready from the first second. No mission pays to install them.

You can do everything on this page from the console (Sandboxes), the ship CLI, the API and the MCP server.

Define a sandbox

A sandbox is a short Dockerfile with no FROM line, because it always starts from the platform base.

RUN export DEBIAN_FRONTEND=noninteractive && apt-get update \
  && apt-get install -y --no-install-recommends python3 python3-venv python3-pip \
  && rm -rf /var/lib/apt/lists/*
RUN python3 -m venv /opt/uv && /opt/uv/bin/pip install uv==0.8.22 \
  && ln -sf /opt/uv/bin/uv /usr/local/bin/uv
ENV UV_LINK_MODE=copy

SHIP supports RUN, ENV, ARG and WORKDIR. It accepts LABEL and EXPOSE but ignores them. A sandbox has no build context, so SHIP refuses COPY and ADD. To get files, download them in a RUN step. Agents run as root, so SHIP also refuses USER. Each refusal gives the line and the reason.

note

The platform manages Node, pnpm, git and the agent CLIs. If a build installs, upgrades or shadows one of them, the build fails and gives its name. The agents need the exact versions that the platform supplies.

You can edit a starter (Python, Java, Go, Rust, Ruby), or you can use your own definition:

ship sandbox starters
ship sandbox create --name python-uv --starter python --wait
ship sandbox create --name ml --file ml.Dockerfile --size 2x8192x16000 --wait

In the console, use Sandboxes → New sandbox.

Builds

When you save a change, SHIP builds it immediately. A build has four phases, and its log streams while it runs:

PhaseWhat happens
ValidateSHIP checks the definition and the size
Run stepsYour steps run on the platform base
SnapshotSHIP takes a snapshot of the result
Warm startA sandbox starts from the snapshot once, so the first mission does not wait for it
ship sandbox build python-uv --wait      # build the active version and stream its log
ship sandbox logs python-uv --follow     # follow the latest build

If the build fails, --wait and --follow exit with code 7 and give the reason from the build. A script can then stop on it.

SHIP also rebuilds a sandbox automatically in two cases: when the platform base changes, and when a snapshot is unused for 25 days. In the second case, the rebuild comes before the snapshot reaches its 30-day retention limit. If a build fails on your steps, SHIP does not try it again until you change the definition. If a build fails because of a problem on the platform side, SHIP tries it again after 10 minutes, up to five times.

Versions and rollback

Each change that you save to the definition or the size makes a new version. The new version becomes active, and SHIP builds it. A new name does not make a new version. If a mission starts while the new version builds, the mission waits for the build. If the build fails, the mission stops and gives the reason from the build.

ship sandbox update python-uv --file sandbox.Dockerfile --wait
ship sandbox versions python-uv
ship sandbox rollback python-uv --to 2

If the snapshot of that version still exists, a rollback is instant. If not, SHIP rebuilds the version first. In the console, the sandbox page lists the versions and their build status. Select Use this version to go back to one of them.

Choose where agents run

SHIP uses the first item in this list that applies:

  1. A per-mission override: ship delegate … --sandbox <name>, or agents.<role>.sandbox in the API's agents-override.
  2. agents.<role>.sandbox in ship.yml, set to the name or id of a sandbox.
  3. A .ship/sandbox.Dockerfile in your repository.
  4. The project's default sandbox.
  5. The platform base.
version: 1

agents:
  builder:
    sandbox: python-uv
  qa:
    sandbox: python-uv
    size: standard-3

deployments:
  # ...

To set or clear the project default, use the CLI or the project settings in the console:

ship sandbox default python-uv --project prj_123
ship sandbox default none --project prj_123

SHIP reads ship.yml and .ship/sandbox.Dockerfile from your default branch, never from the pull request under review. So a pull request cannot change the sandbox that reviews or tests it.

SHIP builds a .ship/sandbox.Dockerfile the first time a mission sees its content. That mission waits for the build and says so on its timeline. SHIP lists this sandbox with the other sandboxes, but you edit it in the repository.

If a ship.yml entry names a sandbox that no longer exists, the dispatch for that role fails and gives the name. The agent does not run in a sandbox that you did not choose. You cannot delete a sandbox while it is a project's default.

Sizes

A sandbox has a default size. To change it for a role, use agents.<role>.size (or --size on ship delegate). Use a tier:

TiervCPUMemoryDisk
standard-11/24 GiB8 GB
standard-216 GiB12 GB
standard-328 GiB16 GB
standard-4412 GiB20 GB

Or use a custom shape: { vcpu, memoryMib, diskMb } in ship.yml and the API, or <vcpu>x<memoryMib>x<diskMb> on the CLI. A custom shape has these limits:

  • 1 to 4 vCPU
  • at least 3072 MiB of memory for each vCPU, and at most 12288 MiB
  • 8000 to 20000 MB of disk

If you set no tier and no custom shape, agents get standard-4.

Private registries

For each package registry host that your builds and agents install from, store a token or a username and password. Examples are npm.pkg.github.com and a company PyPI mirror. The CLI reads the secret from a file, so the secret never goes into your shell history:

ship sandbox registry set --host npm.pkg.github.com --token-file gh-packages.txt
ship sandbox registry set --host pypi.acme.io --username ci --password-file pypi.txt
ship sandbox registry list
ship sandbox registry remove npm.pkg.github.com

In the console, use Sandboxes → Private registries.

SHIP attaches the credential only to requests for that host, when the requests leave the sandbox. This applies when a sandbox builds and when agents run. The credential never goes into the sandbox, its build log or its snapshot. After you save it, SHIP never shows it again. Git hosts and the hosts of the model providers are reserved, and you cannot register them.

API and agents

Everything above is available through the API and the MCP server, so an agent can create a sandbox and follow its build without the console:

  • The API: /v1/sandbox-templates, /v1/sandbox-registries, and defaultSandboxTemplateId on PATCH /v1/projects/{projectId}.
  • The MCP server: save_sandbox_template, build_sandbox_template, get_sandbox_build_log, activate_sandbox_template_version, save_sandbox_registry and others.

The command reference lists every ship sandbox flag.

How is this page?

On this page