Goal: move environment preparation out of every run
Installing Git, Python, Node.js, and test tools after every sandbox creation magnifies startup time, network variance, and supply-chain risk. Templates move stable dependencies into a build stage and produce reusable versioned environments.
This lab builds a base template with Git, Python, curl, a working directory, and a health service. Repositories and short-lived credentials are still injected per run.
- Template: system packages, pinned tools, non-sensitive configuration, and base services.
- Run: repositories, task input, short-lived tokens, network policy, and user data.
Define the environment and readiness in the SDK
The current E2B template SDK starts from Debian-family base images and can install packages, copy files, set users and workdirs, and define start and ready commands.
Do not rely only on a fixed sleep for readiness. A port, URL, file, or custom health command proves more accurately that the process is usable when the snapshot is taken.
import { Template, waitForPort } from "e2b";
export const codingAgent = Template()
.fromUbuntuImage("24.04")
.aptInstall(["git", "python3", "python3-pip", "curl", "ca-certificates"])
.setWorkdir("/workspace")
.setEnvs({
PYTHONDONTWRITEBYTECODE: "1",
PYTHONUNBUFFERED: "1",
})
.setStartCmd(
"python3 -m http.server 8000 --directory /workspace",
waitForPort(8000),
);Record the immutable build ID
Names and tags are human-friendly; a build ID is the stronger reproduction key. CI should retain the template name, tag, build ID, SDK version, source commit, and verification time.
The official docs support environment tags and assigning stable or staging to an already-verified build without rebuilding it.
import "dotenv/config";
import { Template, defaultBuildLogger } from "e2b";
import { codingAgent } from "./template";
const build = await Template.build(codingAgent, "goclaw-coding:v0.1.0", {
cpuCount: 2,
memoryMB: 2048,
onBuildLogs: defaultBuildLogger(),
});
console.log({
buildId: build.buildId,
templateId: build.templateId,
});A successful build is not proof of runtime readiness
Every release tag should start a real sandbox and verify tool versions, default user, workdir, health port, file permissions, and network policy. Promote the build ID to stable only after this smoke test passes.
Tests must explicitly clean up the sandbox and redact failure output. CI should retain build logs and smoke results as capability evidence.
import "dotenv/config";
import { Sandbox } from "e2b";
const sandbox = await Sandbox.create("goclaw-coding:v0.1.0");
try {
const versions = await sandbox.commands.run(
"git --version && python3 --version && curl -fsS http://localhost:8000"
);
if (versions.exitCode !== 0) throw new Error(versions.stderr);
console.log(versions.stdout);
} finally {
await sandbox.kill();
}Versioning, cache, and rollback strategy
Template builds use layer caching, but cache is not version semantics. Create a new semantic version after dependency changes instead of silently drifting one stable tag. Verify an immutable build ID, then move stable.
Kernel versions are also tied to template build time. The official docs state that older templates cannot upgrade their kernel in place and must be rebuilt. Kernel, base-image, and SDK upgrades should therefore produce new conformance evidence.
- dev: fast iteration without long-term reproduction guarantees.
- staging: complete smoke and agent workload tests.
- stable: points only to a verified build ID.
- deprecated: preserves a migration window and replacement.
Six more checks before production
A template is only one part of the supply chain. Before running agent workloads, validate network egress, credential injection, resources, concurrency, output limits, and timeout reclamation.
- Deny network by default, then allow by domain or IP policy.
- Use short-lived credentials; never bake secrets into a template.
- Budget CPU, memory, disk, concurrency, and total cost.
- Treat command output, PTY, Markdown, and artifacts as untrusted.
- Record provider timeout and client timeout separately.
- Run the same workload against E2B and other providers for conformance.
Primary sources and further reading
Technical details in this article come from the official documentation and repositories below. Check the documentation for your version before implementation.