Skip to content
Home

Sandbox Templates

Templates define the image, resources, env vars, startup behavior, readiness checks, and storage mounts used when a sandbox starts.

Use official templates for first runs. Build custom templates when repeated setup should become reusable infrastructure.

Build a custom template when you need to:

  • install dependencies once instead of on every sandbox start
  • copy source code into a reusable image
  • pin versions of OS packages and language packages
  • define startCmd and readyCmd
  • attach persistent storage paths through template policy
  • promote known-good builds through tags such as stable or prod
GoalStart with
Shell commands and file operationsbase
Code interpreter and data analysiscode-interpreter
Node frontend or API servicenode or web-frontend
Python service or scriptspython
Browser automationbrowser
Durable workspacenfs, cloud, block, or a custom tpl-...
Production repeatabilityconcrete tpl-...
import { Sandbox, Template, waitForPort } from "@seacloudai/sandbox";
const built = await Template.build(
new Template()
.fromNodeImage("20-alpine")
.copy("./my-app", "/app", { forceUpload: true })
.runCmd("cd /app && npm install")
.runCmd("cd /app && npm run build")
.setStartCmd("cd /app && npm start", waitForPort(3000)),
"my-app:v1",
{ wait: true },
);
const app = await Sandbox.create(built.templateId, { waitReady: true });
console.log(app.getHost(3000));
  1. Create template metadata with POST /api/v1/templates.
  2. Package local source as .tgz.
  3. Upload the archive through the build context handshake.
  4. Start a build through /api/v1/templates/:templateID/builds/:buildID.
  5. Poll status until ready.
  6. Create sandboxes from the returned templateID.

The public build flow deduplicates local source archives by hash.

GET /api/v1/templates/:id/files/:hash
X-API-Key: <token>

The response may include a signed upload URL and maxContextBytes.

{
"present": false,
"url": "https://storage.googleapis.com/...",
"maxContextBytes": 104857600
}

The default single archive limit is 100MiB. Exclude .git, node_modules, dist, .next, cache directories, and generated build output before upload.

StatusMeaning
uploadedWaiting for the referenced build context upload.
waitingBuild accepted and queued.
buildingBuild job is running.
readyBuild finished and the template image is usable.
errorBuild failed.

Build status responses may include timeline, steps, logs, logEntries, and reason. Use timeline and steps for progress UI, then show logs for details.

Tags are build-version pointers. A reference such as my-template:stable resolves to the build image bound to the stable tag, not necessarily the template’s latest currentBuildId.

POST /api/v1/templates/tags
X-API-Key: <token>
Content-Type: application/json
{
"target": "my-template:v1",
"tags": ["stable", "prod"]
}

The public build route currently accepts structured build steps rather than raw Dockerfile bodies.

Dockerfile instructionBuild payload
FROM node:20fromImage: "node:20" or official base reference
WORKDIR /appWORKDIR step
COPY . /appCOPY step with filesHash
RUN npm installRUN step
ENV NODE_ENV=productionENV step
CMD npm startstartCmd
ModeMeaning
managednano-executor runtime APIs are available on the runtime port, usually 9000.
plainThe image owns its foreground application process; nano-daemon can still provide probes and heartbeat.

workdir controls default process and file roots. It does not create persistent storage. Storage topology comes from template volumeMounts.

Use startCmd to start long-running application processes for future sandboxes. Use readyCmd to decide when a sandbox created from the template is usable.

Good readiness checks are local, bounded, and aligned with the port users will open:

Terminal window
wget -q -O- http://127.0.0.1:3000/ >/dev/null

Avoid checks that only prove a process exists but not that the app is ready:

Terminal window
ps aux | grep node

startCmd and readyCmd use shell semantics. The image should include /bin/sh, or the command should be written for the shell available in that image.

PatternRecommendation
HTTP appstartCmd starts the server; readyCmd curls the local app port.
Background workerreadyCmd checks a health file, PID, queue connection, or worker heartbeat.
Frontend previewBind 0.0.0.0; readyCmd checks 127.0.0.1:<port>; users open getHost(port).
Heavy dependency setupMove install steps into build RUN steps, not sandbox startup.
SymptomCheck
Build stays uploadedArchive upload is missing, filesHash changed, or build started before upload completed.
COPY filesHash is requiredEach COPY step using local source needs a filesHash.
Sandbox starts but preview returns 502startCmd exited, wrong port, or app only binds localhost.
readyCmd times outThe service did not respond on the expected localhost port inside the sandbox.