Agent services
Sandbox images
Start a sandbox from Kuiper's ready-made images for documents, coding, coding agents, video and data by name, without building, publishing or allowlisting an image.
On this page
Images you can start by name#
Kuiper keeps a catalog of ready-made sandbox images. A unit that declares capabilities.sandbox starts one as kuiper/<name>, with no image to build or publish and no allowlist entry:
docker run -d --network none kuiper/coding| Name | Builds on | What it adds |
|---|---|---|
kuiper/base | Debian 12 | git, curl, jq, ripgrep, unzip and zip, procps, less, openssh-client, tini, Python 3.11 with venv and uv, Node.js 22 with npm and corepack |
kuiper/documents | base | LibreOffice (headless), pandoc, poppler-utils, qpdf, fonts with CJK and emoji, python-docx, python-pptx, openpyxl, pypdf, pdfplumber, reportlab, the docx and pptxgenjs Node libraries, and Playwright with headless Chromium for HTML to PDF |
kuiper/coding | base | Build tools, cmake, sqlite3, Go, Rust with rustup, the GitHub CLI, and pnpm and Yarn |
kuiper/coding-agents | coding | OpenCode, the OpenAI Codex CLI with codex-acp, the Gemini CLI, and an installer for Claude Code |
kuiper/video | base | ffmpeg, ImageMagick, sox, fonts, Pillow, NumPy, OpenCV and MoviePy |
kuiper/data | base | NumPy, pandas, SciPy, Matplotlib, DuckDB, PyArrow and Polars |
kuiper/full | coding-agents | Everything above |
Every image runs as the user sandbox (uid 1000) in /workspace, and its default command is sleep infinity, so a sandbox started without a command stays up for docker exec. pip install and npm install -g work without root. Like every sandbox, it runs under gVisor within your unit's limits: the catalog only picks the image.
In the dashboard, the Images tab of the project's Sandboxes page lists them with their contents and a snippet to copy for each way of starting one. From the CLI:
kuiper sandbox images
kuiper sandbox images --jsonDeclare the ones you use#
The images are large, so a node only has the ones its units ask for. List them in kuiper.json and the unit's node pulls them ahead of time:
"capabilities": {
"sandbox": { "maxConcurrent": 4, "images": ["documents", "coding-agents"] }
}An image you don't declare still works, but is pulled the first time a sandbox needs it. Station never pulls an image itself, so declare the ones a Station daemon uses. A name this Kuiper's catalog doesn't have doesn't stop a deploy; the project's Activity says which names are missing.
Start one#
From Station, set the sandbox adapter's image to the name:
new ContainerSandboxAdapter({ image: "kuiper/coding", rootDir: "/data/workspaces", network: "none" });From your own code, use the unit's Docker socket as you would any Docker:
docker run -d --name work --network bridge kuiper/coding-agents
docker exec -i -e OPENAI_API_KEY work codex-acpThe runtime API takes the same name: CreateChild with capability sandbox and image kuiper/data. A name the catalog doesn't have is refused with the list of names it has.
Versions#
kuiper/coding is the current version, and kuiper/coding:1.0.0 holds one version. When the operator publishes a new version, a sandbox that asks for the old one is refused with a message naming the current one, so nothing changes under you without you knowing. Each image is pinned by digest, so every node runs the same bytes.
Claude Code and the other coding agents#
kuiper/coding-agents and kuiper/full include OpenCode (MIT), the OpenAI Codex CLI and codex-acp (Apache-2.0) and the Gemini CLI (Apache-2.0), whose licences allow Kuiper to redistribute them.
Claude Code is proprietary software from Anthropic, so Kuiper doesn't put it in an image. The image has an installer that downloads it into the sandbox user's home the first time you need it, once you accept Anthropic's terms yourself:
kuiper-install-agent claude-code --accept-termsThe sandbox needs network access for that (--network bridge). The same command installs a newer release of the other agents for one sandbox, such as kuiper-install-agent codex 0.160.0. Pass each agent its API key for that one process with docker exec -e, not in the container's environment.
Your own image#
Images of your own work as before, once the operator allowlists them. To add a few tools, build on a catalog image, FROM ghcr.io/porkytheblack/kuiper-sandbox-coding:1.0.0, publish it and ask for it to be allowlisted. Names under kuiper/ always mean the catalog, never Docker Hub's kuiper organisation.
Station units covers the Docker socket and what it allows.