LelantosLelantos
Templates

Custom Templates

Build custom templates from Dockerfiles.

Overview

Custom templates let you define your own sandbox environment from a Dockerfile. You can install any packages, configure runtimes, set up tools, and specify resource allocation. The build process is asynchronous -- you submit the Dockerfile and poll for build completion.

Creating a Custom Template

const template = await client.createTemplate({
  dockerfile: `
FROM python:3.12-slim
RUN pip install numpy pandas scikit-learn matplotlib
`,
  alias: "data-science",
  cpuCount: 4,
  memoryMB: 2048,
});

console.log("Template ID:", template.templateID);
console.log("Build ID:", template.buildID);
curl -X POST https://api.lelantos.ai/templates \
  -H "X-API-Key: lel_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "dockerfile": "FROM python:3.12-slim\nRUN pip install numpy pandas scikit-learn matplotlib",
    "alias": "data-science",
    "cpuCount": 4,
    "memoryMB": 2048
  }'

Template Configuration

ParameterTypeDefaultRangeDescription
dockerfilestring(required)--Dockerfile content as a string.
aliasstring(optional)--Human-readable name for the template.
cpuCountnumber21 - 8Number of vCPUs for sandboxes created from this template.
memoryMBnumber512128 - 8192Memory in MB for sandboxes created from this template.

Checking Build Status

Template builds are asynchronous. Poll the build status to know when the template is ready:

const status = await client.getTemplateBuildStatus(
  template.templateID,
  template.buildID,
);

console.log("Status:", status.status);
// "building" | "ready" | "error"

if (status.status === "error") {
  console.error("Build failed:", status.error);
}
curl "https://api.lelantos.ai/templates/TEMPLATE_ID/builds/BUILD_ID" \
  -H "X-API-Key: lel_your_key_here"

Build Status Values

StatusDescription
buildingTemplate is currently being built.
readyBuild completed successfully. Template is ready to use.
errorBuild failed. Check the error message for details.

Polling Example

async function waitForBuild(client, templateID, buildID) {
  while (true) {
    const status = await client.getTemplateBuildStatus(templateID, buildID);

    if (status.status === "ready") {
      console.log("Template is ready!");
      return;
    }

    if (status.status === "error") {
      throw new Error(`Build failed: ${status.error}`);
    }

    // Wait 2 seconds before checking again
    await new Promise((r) => setTimeout(r, 2000));
  }
}

await waitForBuild(client, template.templateID, template.buildID);

// Now create a sandbox from the template
const sandbox = await client.createSandbox({
  templateID: template.templateID,
});

DNS

Do not add RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf to your Dockerfile. Older versions of this guide recommended it as a workaround, but Docker BuildKit mounts /etc/resolv.conf read-only during builds and the line now fails with Read-only file system. DNS works without it — apt-get, pip install, npm install, etc. resolve normally during the build. If you copied an older template that includes this line, just remove it before rebuilding.

Rebuilding a Template

To update an existing template, create a new template with the same alias. The new build will produce a new template ID. Existing sandboxes running on the old template are not affected.

const updated = await client.createTemplate({
  dockerfile: `
FROM python:3.12-slim
RUN pip install numpy pandas scikit-learn matplotlib seaborn
`,
  alias: "data-science",
  cpuCount: 4,
  memoryMB: 4096, // Increased memory
});

Deleting a Template

Remove a template when it is no longer needed:

await client.deleteTemplate(template.templateID);
curl -X DELETE "https://api.lelantos.ai/templates/TEMPLATE_ID" \
  -H "X-API-Key: lel_your_key_here"

Deleting a template does not affect running sandboxes that were created from it. They will continue to run until they are killed or their timeout expires.

On this page