Creating Templates from OCI Images
This guide explains how to create, monitor, and delete a template from a standard OCI container image.
Before you begin, consider reading Templates Overview to understand the related concepts, including OCI images, template snapshots, ports, probes, and envd.
Prerequisites
cubemastercliinstalled and able to connect to CubeMaster- The OCI image must be accessible from the CubeMaster nodes (public registry or authenticated private registry)
Plain HTTP registries (without TLS) must use an
http://prefix, for examplehttp://harbor.internal:5000/ns/app:tag. Without the prefix, CubeMaster uses HTTPS by default, except for localhost and RFC1918 addresses.
Step 1 — Select an OCI Image
create-from-image accepts an OCI image that has already been built and published. This guide uses the CubeSandbox base image, which includes envd:
ghcr.io/tencentcloud/cubesandbox-base:latestThe image runs envd on port 49983 by default, so GET /health can be used directly as the template probe.
For custom template images and guidance on integrating other existing images with CubeSandbox, see Custom Template Images.
Step 2 — Create the Template from the Image
Use the tpl create-from-image sub-command to kick off the build job:
cubemastercli tpl create-from-image \
--image ghcr.io/tencentcloud/cubesandbox-base:latest \
--writable-layer-size 1G \
--expose-port 49983 \
--probe 49983 \
--probe-path /healthPass
--backend s3to store the template (and every sandbox / snapshot derived from it) on the cluster-shared S3 CoW backend. That is required for cross-node Pause / Resume / FromSnap. Omit the flag to keep the historicalxfspath.
Template creation can expose multiple ports, use a custom probe path, and pass environment variables:
cubemastercli tpl create-from-image \
--image cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest \
--writable-layer-size 1G \
--expose-port 49999 \
--expose-port 49983 \
--probe 49999 \
--probe-path /health \
--env MY_ENV=productionStep 3 — Monitor Progress
There are two ways to follow the build job.
Watch (blocking, recommended)
tpl watch polls the job in a loop and exits only when the job reaches a terminal state (READY or FAILED):
cubemastercli tpl watch --job-id <job_id>Example output when the job completes:
job_id: 2e71b561-153e-4c08-ac37-5270d94f5f15
template_id: tpl-748094d2f2374b0a8a37e6ec
attempt_no: 1
artifact_id: rfs-1e8e07c90e9bb8eff94ecde2
status: READY
phase: READY
progress: 100%
distribution: 1/1 ready, 0 failed
template_spec_fingerprint: 1e8e07c90e9bb8eff94ecde20396002c411f6b812612a2a05086b85fe245b858
artifact_status: READY
artifact_sha256: 5d413bc735062d49d36ef9c0e62cd0c3a915853be5ec0c7fba90e13d9fd33f79
template_status: READYKey output fields:
| Field | Description |
|---|---|
status / template_status | Overall job and template state. READY means the template is usable. |
phase | Current pipeline phase: PULLING → BUILDING → DISTRIBUTING → READY. |
progress | Percentage completion of the current phase. |
distribution | N/M ready — how many cluster nodes have received the artifact. |
artifact_id | Stable ID of the built rootfs artifact. |
artifact_sha256 | SHA-256 digest of the rootfs artifact for integrity verification. |
template_spec_fingerprint | Deterministic fingerprint of the full template spec (image + flags). Same input always produces the same fingerprint. |
Status (single snapshot)
If you only want a one-shot status check without blocking:
cubemastercli tpl status --job-id <job_id>Step 4 — Use the Template
Once template_status: READY, reference the template_id when creating sandboxes via the E2B SDK:
export CUBE_TEMPLATE_ID=tpl-748094d2f2374b0a8a37e6ec
python CubeAPI/examples/create.pyQuerying Templates
List all templates
cubemastercli tpl listOutput:
TEMPLATE_ID INSTANCE_TYPE STATUS CREATED_AT IMAGE_INFO
tpl-748094d2f2374b0a8a37e6ec cubebox READY 2026-04-02T08:10:30Z docker.io/library/nginx:latest@sha256:abcd...
tpl-4ff5adc5eea44c14b1c8dbb3 cubebox READY 2026-04-01T17:42:11Z docker.io/library/python:3.11CREATED_AT is returned in UTC RFC3339 format. IMAGE_INFO shows image reference and digest when available (image@sha256:...), and falls back to the image reference when digest is unavailable.
Use wide output when you need VERSION and LAST_ERROR:
cubemastercli tpl list -o wideAdd --json to get the full JSON payload for scripting:
cubemastercli tpl list --json | jq '.data[].template_id'Inspect a single template
cubemastercli tpl info tpl-748094d2f2374b0a8a37e6ecThe template ID can be passed as a positional argument (docker/kubectl style) or with --template-id; both forms are equivalent.
Add --json for machine-readable output:
cubemastercli tpl info tpl-748094d2f2374b0a8a37e6ec --jsonAdd --include-request when you want to inspect the stored template request body:
cubemastercli tpl info tpl-748094d2f2374b0a8a37e6ec --json --include-requestIf you want to preview the effective sandbox payload after template resolution, use:
cubemastercli tpl render --template-id tpl-748094d2f2374b0a8a37e6ec --jsonFor a user-oriented walkthrough of what each output means and how to preview the effective request, see Template Inspection and Request Preview.
Deleting a Template
cubemastercli tpl delete tpl-748094d2f2374b0a8a37e6ecOn success:
template deleted: tpl-748094d2f2374b0a8a37e6ec⚠️ Deletion removes both the template metadata and all node-local artifact replicas. Any sandboxes already running from this template are not affected, but new sandboxes can no longer be created from it.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
phase: PULLING stuck for a long time | Image pull slow or registry unreachable from cluster nodes | Check network/firewall; for private registries add --registry-username / --registry-password |
Plain HTTP registry pull fails (server gave HTTP response to HTTPS client) | Image ref is missing the http:// prefix | Use http://harbor.internal:5000/ns/app:tag |
status: FAILED after BUILDING | Build error (disk full, Dockerfile issue, etc.) | Re-run tpl status --job-id <id> --json and inspect last_error |
distribution: 0/N ready after READY | Artifact distribution still in progress (normal briefly) | Wait and re-run tpl info; if stuck check Cubelet logs on target nodes |
| Sandbox readiness probe keeps failing after startup | The service is not listening on the expected port/path, or the HTTP server started before the service was fully ready | Ensure the HTTP server starts only after the application is fully ready, and verify that --probe-path is correct |