Templates#
A template is a reusable starting point for new sandboxes. Every template is stored as a RAM snapshot of a booted VM, so a sandbox created from it starts from a ready system instead of booting (target p95 < 500 ms).
Official templates#
| Template | Contents |
|---|---|
base |
Ubuntu 24.04, systemd, Docker, Python 3.12, common build tools; user user with passwordless sudo |
python, node, browser, coding-agent, jupyter |
language runtimes, a headless browser, coding-agent tools or JupyterLab, ready in one call; see the Template gallery |
desktop |
base + XFCE, KasmVNC, Chromium, Firefox, xdotool and fonts; desktop is already running. Needs size default or larger |
template defaults to base when you create a sandbox without a source.
Your own templates#
Create a template from either an OCI/Docker image or a snapshot.
From an OCI image#
We pull the image (linux/amd64), turn it into a VM root filesystem and add our guest agent. If the image has systemd, the agent and start_command run as systemd services; if it doesn't, a small init (taskcloud-init) starts the agent and your start_command (or the image's ENTRYPOINT/CMD). We then boot it, wait for ready_check to exit 0, and take a RAM snapshot. The call returns 202 with state building.
const tpl = await client.templates.create({
name: "agent-env",
image: { ref: "ghcr.io/acme/agent-env:1.4", registry_auth: { username: "acme-bot", password: process.env.GHCR_TOKEN! } },
start_command: "/usr/local/bin/warmup.sh",
ready_check: { command: "curl -sf localhost:8080/health", timeout_seconds: 120 },
size: "default",
});
tpl = client.templates.create(
name="agent-env",
image={"ref": "ghcr.io/acme/agent-env:1.4",
"registry_auth": {"username": "acme-bot", "password": os.environ["GHCR_TOKEN"]}},
start_command="/usr/local/bin/warmup.sh",
ready_check={"command": "curl -sf localhost:8080/health", "timeout_seconds": 120},
size="default",
)
curl -sS -X POST https://api.task.cloud/v1/templates \
-H "Authorization: Bearer $TASKCLOUD_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"agent-env","image":{"ref":"ghcr.io/acme/agent-env:1.4"},"size":"default"}'
taskcloud template create --name agent-env --image ghcr.io/acme/agent-env:1.4
taskcloud template logs agent-env --follow
Follow the build with GET /templates/{template_id}/logs (plain text, or SSE with Accept: text/event-stream). The template becomes ready or failed (see error).
Image build options:
| Field | Notes |
|---|---|
image.ref |
OCI reference, linux/amd64 |
image.registry_auth |
username, password (write-only) for private registries |
start_command |
started before the snapshot |
ready_check |
command that must exit 0; timeout_seconds default 300, max 1800 |
env |
baked into the template |
desktop |
true adds the XFCE + KasmVNC desktop stack (coming soon for custom images; use the desktop base template today) |
size |
size used for the build snapshot |
From a snapshot#
Set up a sandbox by hand or with exec, take a named snapshot, then turn it into a template. It is ready immediately (201) and keeps that exact RAM and disk state.
const snap = await sandbox.snapshots.create({ name: "python-preinstalled" });
await client.templates.create({ name: "python-preinstalled", snapshot_id: snap.id });
taskcloud template create --name python-preinstalled --snapshot snap_3kd7wq2mzn5x
Versions#
Creating a template with an existing name adds a new version. template: "agent-env" uses the latest ready version; pin one with template: "agent-env:3". Deleting a template does not affect sandboxes already created from it.
const sbx = await client.sandboxes.create({ template: "agent-env:3" });
Templates vs. images vs. snapshots#
- Use an image directly (
POST /sandboxeswithimage) for one-offs. Each create converts and boots the image, so it is slower than a template. - Use a template for anything you start often.
- Use a snapshot to continue from one specific sandbox's state. See Snapshots and fork.
Template storage is billed like snapshot storage. See Billing.