Templates · Authoring
Defining a template
A template is the image your sandboxes start from. You can author one as a Dockerfile or, with the new Template SDK, as a typed JS or Python builder.
Two authoring formats
GROTTE templates can be defined two ways. Both compile to the same internal layer set the orchestrator builds.
| Format | File | When to use |
|---|---|---|
| Dockerfile | grotte.Dockerfile (or fallback Dockerfile) | You already have a Dockerfile or you want maximum portability. |
| Template SDK | grotte.template.ts / grotte_template.py | You want type-safety, ESM/PyPI deps, programmatic builds, or to compose templates. |
Pick one. The grotte template create and grotte template build
commands accept both.
Dockerfile format
Default base image — anything Debian-based works:
# grotte.Dockerfile
FROM ubuntu:22.04
# Install whatever you need
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install pandas numpy
# (Optional) bake project files in
COPY ./src /opt/sandbox
# (Optional) set the working directory new sandboxes start in
WORKDIR /opt/sandboxGROTTE supports the standard subset of Dockerfile instructions:
FROM, RUN, ENV, USER, WORKDIR, COPY. The orchestrator
unpacks these into internal layers — there's no docker build on the
client side.
Build it:
grotte template create my-envIf you don't pass --dockerfile, the CLI looks for
grotte.Dockerfile first, then falls back to Dockerfile in the
working directory.
Template SDK format
For type-safe template authoring, the SDK exposes Template() (JS)
and Template() / AsyncTemplate() (Python). Output of the
grotte template init scaffold:
JavaScript / TypeScript (grotte.template.ts):
import { Template } from "grotte";
export const template = Template()
.fromImage("ubuntu:22.04")
.runCmd("apt-get update && apt-get install -y python3 python3-pip")
.runCmd("pip install pandas numpy")
.copy("./src", "/opt/sandbox")
.setWorkdir("/opt/sandbox");Python (grotte_template.py):
from grotte import Template
template = (
Template()
.from_image("ubuntu:22.04")
.run_cmd("apt-get update && apt-get install -y python3 python3-pip")
.run_cmd("pip install pandas numpy")
.copy("./src", "/opt/sandbox")
.set_workdir("/opt/sandbox")
)Same instructions as Dockerfile — from_image, run_cmd, copy,
set_workdir, set_envs, set_user, set_start_cmd, set_ready_cmd
— but as typed builder methods you can compose, conditionally include,
and unit-test.
Start command + readiness probe
If your template runs a long-lived process (a Gradio app, a FastAPI
server, a dev server), tell GROTTE about it. The CLI accepts both
flags on grotte template create:
grotte template create my-env \
--cmd "node server.js" \
--ready-cmd "curl -fsS http://localhost:3000/health"--cmd runs in the background as sudo, with the cwd at your
template's WORKDIR. --ready-cmd runs in a loop until it exits 0;
the sandbox is reported ready only after that. Without
--ready-cmd, "ready" means "process spawned" — which often races
with apps that take a few seconds to bind.
CPU + memory
Defaults: 2 CPUs, 512 MB RAM. Override at build time:
grotte template create my-env \
--cpu-count 4 \
--memory-mb 2048--memory-mb must be even (the orchestrator allocates RAM in 2-MB
hugepages).
Naming rules
Template names must match [a-z0-9-_]+ — lowercase letters, digits,
dashes, underscores. The CLI rejects anything else with a clear
error before contacting the API.
Try it
grotte template init # scaffold a fresh template directory
grotte template create my-first-env # build it
grotte sandbox create my-first-env # use itOr skip the CLI and build via the dashboard.
Related
- v1 → v2 migration — if you used the
legacy
grotte template buildcommand before. - Build authentication error — for self-hosted deployments hitting docker-login failures.