---
title: How to Use a Custom Sandbox Template (BYOT) (public)
description: Build a Container Registry image, register it as a Harness Runtime template, and start a session from it.
product: Managed Agents
url: https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/use-custom-template/
last_updated: "2026-10-07"
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# How to Use a Custom Sandbox Template (BYOT) (public)

DigitalOcean Harness Runtime provides managed, hardware-isolated microVM sandboxes with built-in tools such as Chromium to run harnesses and execute arbitrary code. Rich lifecycle APIs preserve conversational history and working state across sessions, letting you pause, resume, and fork work to control costs and adapt to the nonlinear nature of agentic workflows. Scale complete agents such as Claude Code or use sandboxes independently for code execution, all through the same service. See [What You Can Build](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/what-you-can-build/index.html.md) for example use cases.

Harness Runtime sandboxes start from a template that defines what is preinstalled in the microVM. Platform templates cover adapters such as Codex, Claude Code, and OpenCode. Bring-Your-Own-Template (BYOT) lets you register a team-owned OCI image so sessions start from your dependencies, CLIs, and configuration instead of only the catalog image.

DigitalOcean builds your image on top of a required base template (for example `codex-base`) when you register it. Sessions that set `template` to your custom template name use that environment.

## What Your Image Is For

The agent comes from the base template (`codex-base` runs Codex, `hermes-base` runs the platform Hermes agent, and so on). Your OCI image supplies tools, dependencies, and an optional sidecar process. It does not replace the chat backend or act as a bring-your-own agent.

## Prerequisites

You need:

- A DigitalOcean account with a payment method on file and [funds in at least one balance](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/pay-for-harness-runtime/index.html.md).
- A DigitalOcean [personal access token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md) with write access.
- [`doctl`](https://docs.digitalocean.com/reference/doctl/how-to/install/index.html.md) authenticated for your account, with Harness Runtime commands available (`doctl harness-runtime --help`).
- A [Container Registry](https://docs.digitalocean.com/products/container-registry/index.html.md) in your team, and Docker (or another OCI client) that can push to it.
- A working environment spec for the adapter you want to run. See [Create an Environment Using a Coding Adapter](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/create-managed-agent/index.html.md).

## Push an Image to Container Registry

Build an image that installs the packages, CLIs, and any background services your agent needs. Push it to [Container Registry](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes/index.html.md). Harness Runtime pulls images from your team’s registry without extra registry credentials in the environment spec.

```shell
docker build --platform linux/amd64 -t registry.digitalocean.com/<your-registry>/custom-agent:v1 .
docker push registry.digitalocean.com/<your-registry>/custom-agent:v1
```

Replace `<your-registry>` with your registry name.

### Image Requirements

Your custom image must meet these requirements before you register it as a template:

- **OS and architecture**: A `linux/amd64` image with `/bin/sh` and Coreutils. Glibc-based images (Debian or Ubuntu) are strongly recommended. musl-based images such as Alpine may work for tooling-only images, but they are not supported by default.
- **Minimum Glibc**: `claude-code-base` and `codex-base` require Glibc 2.28 or later. Other bases require Glibc 2.17 or later.
- **USER**: The image `USER` instruction is ignored. The agent runs as UID `10001`. Your `ENTRYPOINT` or `CMD` runs as root inside its namespace.
- **WORKDIR**: `WORKDIR` still affects relative paths for uploads and exec defaults. Use absolute paths under `/workspace/`.
- **Environment variables**: The platform drops environment keys with the `LD_` or `WORKLOAD_` prefix, plus `GCONV_PATH`, `LOCPATH`, and `NLSPATH`, from the image environment. `PATH` is merged, with the agent directory first. If a tool needs `LD_LIBRARY_PATH`, use a wrapper script or RPATH.
- **Reserved ports**: Do not bind these ports. The platform uses them: `2024`, `4317-4320`, `8443`, `8642`, `9100`, `9101`, `9119`, `49983`, and `50051`.
- **Reserved paths**: Do not use `/package/admin/s6/` or `/.sandbox/`. The platform reserves these paths.

The platform supplies the agent runtime, `bash`, `git`, `gh`, and a CA certificate bundle. If your image includes its own copy of those tools or CA certificates, your copy is used. Install any other tools the agent needs (for example `rg`, `jq`, Python, or compilers) in your image.

If you omit both `ENTRYPOINT` and `CMD`, the platform keeps the session running. If you set either, the behavior depends on the base:

- **`codex-base`, `opencode-base`, and `claude-code-base`:** The command runs as PID 1 and must stay running for the session. Do not rely on an inherited default such as `bash`, which is common with Ubuntu and Debian base images. With no terminal, `bash` exits immediately and the session stops. Use a long-running command instead, for example `sleep infinity`.
- **`hermes-base` and `langgraph-base`:** The process runs once at startup alongside the agent and may exit.

## Register the Template

Create a template that points at your registry image and a base template. The base template supplies runtime wiring (entrypoints and control-plane event handling) that your image alone does not provide. New custom templates must use a recommended base. Harness Runtime rejects legacy bases for new template registrations.

```shell
doctl harness-runtime template create \
  --name custom-finops-agent \
  --base-template codex-base \
  --source-oci-ref registry.digitalocean.com/<your-registry>/custom-agent:v1
```

**Warning**:

  `--base-template` is required. Omitting it causes registration to fail.

Harness Runtime supports the following BYOT base templates:

| Base template | Adapter | Status |
|---|---|---|
| `codex-base` | `codex` | Recommended |
| `opencode-base` | `opencode` | Recommended |
| `claude-code-base` | `claude-code` | Recommended |
| `hermes-base` | `hermes` | Recommended |
| `langgraph-base` | `langgraph` | Recommended |
| `coding-codex` | `codex` | Legacy |
| `coding-opencode` | `opencode` | Legacy |
| `coding-claude-code` | `claude-code` | Legacy |
| `coding-hermes` | `hermes` | Legacy |
| `langgraph` | `langgraph` | Legacy |

Choose the recommended base template that matches the adapter you plan to run.

**Warning**:

  Legacy bases (`coding-codex`, `coding-opencode`, `coding-claude-code`, `coding-hermes`, and `langgraph`) remain available for existing custom templates. You can rebuild those templates with a legacy base. New template registrations must use a recommended base (`codex-base`, `opencode-base`, `claude-code-base`, `hermes-base`, or `langgraph-base`). Support for legacy bases in BYOT will be removed in a future release. Sessions that use these legacy base templates as adapter default templates continue to work as usual.

List templates and wait until the new one shows as ready:

```shell
doctl harness-runtime template list
```

Related commands include `get`, `update`, `delete`, and `list-builds`.

### Rebuild the Template for Platform Updates

Registered templates do not automatically pick up new platform binaries. Rebuild the template when you need platform fixes. Automatic rebuilds are planned for a future release.

Custom template storage is billed per GB. See [Harness Runtime Pricing](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/pricing/index.html.md).

## Start a Session From the Template

Write an environment spec that sets `template` to your registered template name. Keep `agent` aligned with the base template you chose (for example `codex` with `codex-base`):

```yaml
name: finops-session-01
agent: codex
template: custom-finops-agent
secrets:
  OPENAI_API_KEY: ${OPENAI_API_KEY}
```

If you omit `template`, Harness Runtime selects a default template for the adapter. To run a custom template such as `custom-finops-agent`, set `template` explicitly.

Export the key so `doctl` can expand `${OPENAI_API_KEY}`, then create the session:

```shell
export OPENAI_API_KEY=<your-openai-key>
doctl harness-runtime create --spec <your-environment-spec>.yaml
```

To confirm custom binaries are on the path before you attach interactively:

```shell
doctl harness-runtime exec finops-session-01 -- sh -c "which <your-custom-cli> && <your-custom-cli> --version"
```

Attach to the session:

```shell
doctl harness-runtime launch finops-session-01
```

For the full `template` field and other agent fields, see [Environment Spec Reference](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/reference/environment-spec/index.html.md).

## Reach Services Running in the Sandbox

If your image starts a long-lived service on a sandbox port, open a local tunnel with `doctl harness-runtime port-forward`. See [Forward Sandbox Ports](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/forward-ports/index.html.md).

## Troubleshooting

### Template Creation Fails When `--base-template` Is Omitted

`--base-template` is required when you register a template. Harness Runtime uses the base template (for example `codex-base`) for runtime dependencies, entrypoint definitions, and event handling between the sandbox and the control plane. Omitting it causes registration to fail.

### Template Creation Fails With a Legacy Base

New template registrations reject legacy bases. Use a recommended base such as `codex-base`, `opencode-base`, `claude-code-base`, `hermes-base`, or `langgraph-base`. Existing custom templates that already use a legacy base continue to work, and you can still rebuild those templates with the same legacy base until BYOT support for them is removed.

### Skills Are Missing

Skills come from the environment spec, not from the template image. Add them under [`skills`](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/reference/environment-spec/index.html.md#skills) and start a new session. Baking files under `/workspace` in a BYOT image does not work on recommended bases; `/workspace` is platform-owned, as on adapter default templates.