KortixDocs
Reference

Sandbox image

The layered Docker image, what Kortix injects, constraints, examples, and snapshot rebuilds.

The sandbox base image. For how a session uses it at runtime, see Session runtime.

Every session boots inside a Docker container, built in two parts: your Dockerfile defines the environment (languages, tools, system packages), and the Kortix runtime layer is auto-injected on top so the dashboard can connect.

┌─────────────────────────────────────────┐
│  Kortix runtime layer (auto-injected)   │  ← opencode + kortix-agent + ENTRYPOINT
├─────────────────────────────────────────┤
│  Your Dockerfile                        │  ← .kortix/Dockerfile
└─────────────────────────────────────────┘

Referenced from kortix.toml as a named template under [[sandbox.templates]]:

[[sandbox.templates]]
slug       = "dev"             # any slug except the reserved "default"
name       = "Dev box"         # optional label
dockerfile = ".kortix/Dockerfile"   # OR image = "python:3.12-slim"
cpu        = 2     # optional — vCPU cores
memory     = 4     # optional — GiB
disk       = 20    # optional — GiB

# Make a template the project-wide default so every session (UI, triggers,
# channels) boots it without passing a slug. Omit → the platform default.
[sandbox]
default = "dev"

Each entry sets exactly one of dockerfile or image. Paths must be repo-relative — absolute paths and .. traversal are rejected. The singular [sandbox] table with image/build keys on it directly is legacy and rejected; image definitions live under [[sandbox.templates]], and [sandbox] itself only carries default. Field details: kortix.toml.

What the Kortix layer injects

On top of your Dockerfile's final stage, the snapshot builder appends:

  1. USER root (the layer needs to install things).
  2. apt-get install -y ca-certificates curl git gzip nodejs npm unzip tmux.
  3. npm install -g opencode-ai@<pinned-version>, plus the bun runtime and agent-browser (for the headless-browser tool).
  4. A baked OpenCode tool-dependency cache under /opt/kortix/ (so the boot-time bun install in your config dir is a no-op, not a network round-trip).
  5. COPY the kortix-agent daemon, the kortix CLI, and the kortix-entrypoint script to /usr/local/bin/, plus the agent-cli and executor-sdk package trees under /opt/kortix/.
  6. ENV KORTIX_WORKSPACE=/workspace, WORKDIR /workspace, EXPOSE 8000.
  7. ENTRYPOINT ["/usr/local/bin/kortix-entrypoint"].

Everything you installed stays on PATH; the layer relocates and removes nothing.

Constraints

These rules keep a sandbox connectable. They aren't enforced statically — your build succeeds even if you violate them — but the session won't behave correctly.

RuleWhy
Don't set ENTRYPOINT.Kortix overrides it. Your CMD is also ignored.
Don't claim port 8000.Reserved for the daemon's reverse proxy. Run your dev servers on other ports.
FROM a Debian/Ubuntu-family base.The layer assumes apt-get. Alpine, Fedora, Arch will fail at layer build.
Don't RUN apt-get clean without rm -rf /var/lib/apt/lists/*.The Kortix layer re-runs apt-get update; a broken lists cache breaks it.
Don't bake credentials into the image.Use [env] + Secrets Manager — values are injected at session start.

Everything else is fair game: RUN curl … | sh for toolchains, COPY seed data, set ENV for non-secret config, install any apt/npm packages.

Examples

The starter ships a minimal Ubuntu base:

# syntax=docker/dockerfile:1.7
FROM ubuntu:24.04

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        ca-certificates curl git build-essential \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /workspace

A heavier example with Python + Bun:

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y --no-install-recommends \
        ca-certificates curl git python3.12 python3.12-venv unzip \
    && rm -rf /var/lib/apt/lists/* \
    && curl -fsSL https://bun.sh/install | bash

ENV PATH="/root/.bun/bin:${PATH}"
WORKDIR /workspace

Hardware spec

cpu, memory, and disk on a [[sandbox.templates]] entry size the box your sessions run on. All three are optional; an omitted field takes the runtime provider's default. cpu is vCPU cores, memory and disk are GiB. GPUs are not supported in this version — a gpu key is rejected by the manifest validator.

[[sandbox.templates]]
slug   = "big"
image  = "ubuntu:24.04"
cpu    = 4
memory = 8
disk   = 50

The spec is baked into the snapshot, not set per-session: the provider builds each sandbox from your project's snapshot and inherits its size from there. That has one practical consequence — changing the spec rebuilds the snapshot (it's part of the content hash, below) and the new size applies on the next session, exactly like a Dockerfile edit. Values are rounded to whole numbers; a non-positive value falls back to the default, and anything above the platform ceiling (cpu 32, memory 128 GiB, disk 500 GiB) is clamped down. See kortix.toml → [sandbox] for the full field table and aliases.

Snapshot rebuilds

Snapshots are content-addressed: the platform hashes your Dockerfile + the git tree OID of the build context + the hardware spec + a platform runtime fingerprint (opencode version + kortix-agent binary). Unchanged hash reuses the snapshot; otherwise a new one builds. Rebuilds happen on any push touching your Dockerfile or anything COPY'd into it, or any change to the [sandbox] spec — pure code commits reuse the snapshot for free.

Builds run Daytona-side via Image.fromDockerfile. The first session on a new content hash triggers an inline build (a few minutes, shown as "preparing image"); later sessions on the same content hit the cache.

Editing the Dockerfile inside a session takes effect on the next session; current ones keep their booted snapshot. The edit reaches main only once a change request merges it.

Sandbox image | Kortix Docs | Kortix