Daytona

Run your agents in a managed Daytona cloud sandbox seeded from your host repo

Run your agents in a managed Daytona cloud sandbox (default 2 vCPU / 4 GB RAM / 8 GB disk) when the work outgrows your laptop or a teammate needs to attach — no local Docker needed. Each box is a remote Daytona sandbox you drive with the same agentbox commands as a local box, seeded from your host repo.

A Daytona box is a container by default. If your organization is authorized for VM sandboxes, box.daytonaClass: linux-vm upgrades it to a real Linux VM — and then agentbox pause genuinely freezes the box, CPU and memory, so a long build or a running agent picks up exactly where it left off on unpause. No other AgentBox provider preserves running processes across a pause.

VM sandboxes need an authorized Daytona org

Daytona runs VM sandboxes only in a dedicated region — us-east-1 — and dedicated regions are not generally available. Daytona has to enable one for your organization; creating a new org or adding credit does not grant it, and the shared regions (us, eu) have no VM runners at all. That is why container is the default: it works on every account.

Check what yours has before setting box.daytonaClass: linux-vm:

curl -H "Authorization: Bearer $DAYTONA_API_KEY" https://app.daytona.io/api/regions

If the list has no region with "regionType": "dedicated", a linux-vm bake fails with your Daytona organization has no 'us-east-1' region — ask Daytona to authorize your org, or stay on container.

Switch per box with --provider daytona, or pin it project-wide with box.provider: daytona in agentbox.yaml. Comparing options? See local-docker, hetzner, vercel, and e2b.

Sandbox class

Daytona offers two sandbox classes. box.daytonaClass selects one; changing it needs a re-bake (agentbox prepare --provider daytona --force), because the class is baked into the snapshot and a snapshot of one class can't create a box of the other.

container (default)linux-vm
Availabilityevery accountauthorized orgs only (dedicated region)
agentbox pausecold storage (filesystem only)freezes CPU + memory — running processes and tmux sessions survive
Base bake~7 min, from the Dockerfile~1 min, from a published image
Checkpoint capture~2 s~2 s
Regionany (us, eu, …)us-east-1 only

THE TRADEOFF

Daytona runs VM sandboxes in us-east-1 only — it's the sole region with VM runners. Choosing linux-vm therefore pins your boxes to US-East, and needs an org Daytona has authorized. If you need EU data residency or lower EU latency, stay on container and pick a region with box.daytonaRegion.

Idle boxes pause themselves

An idle Daytona box is paused after 25 minutes (box.daytonaTimeoutMs; 0 disables). While an agent is actually working the box is held open, so only a genuinely idle one lapses. A linux-vm box is frozen (memory and running processes survive); a container box is archived to cold storage. Either way the filesystem is preserved, and simply using the box again — agentbox shell, agentbox claude, … — resumes it automatically.

The host does this, not Daytona

Daytona's own idle timer is an inactivity window that any request to the sandbox resets — including the continuous polling AgentBox's host relay does to talk to the box. That polling is itself activity, so Daytona's timer never fires for a box AgentBox is tracking. The host therefore enforces the timeout itself. Daytona's timer remains as a backstop for when the relay isn't running (laptop asleep, agentbox relay stop), which is exactly when the host can't.

One consequence: the timeout is measured against your agent's activity, not raw requests to the box. A box you're only using through an attached shell, with no agent running, is left alone entirely.

Set up

The easiest path is the interactive wizard — it takes your API key and bakes the base snapshot in one flow:

agentbox install        # then select daytona

Paste a DAYTONA_API_KEY when prompted; the wizard offers to open the keys page in your browser first so you can generate one. (There's no browser sign-in — the key is the whole auth. If you paste a JWT instead of an API key, you'll also be asked for a DAYTONA_ORGANIZATION_ID, which an API key doesn't need: the SDK derives the org from it.) Credentials persist to ~/.agentbox/secrets.env; project .env files are never harvested. install also bakes the base snapshot (a one-time agentbox prepare --provider daytona under the hood) with the AgentBox runtime — agentbox-ctl, tmux, the browser stack — so every new box boots in seconds instead of eating a ~7-minute cold Dockerfile build.

For CI or scripted setup, run the explicit equivalents:

agentbox daytona login                 # credentials only
agentbox prepare --provider daytona    # bake the base snapshot

Use it

agentbox daytona claude

agentbox daytona create|claude|codex|opencode|pi is sugar for the same command with --provider daytona.

Prepare image

Unlike Docker, Daytona does not auto-build the box image on first create. Run agentbox prepare --provider daytona once per org: it builds a base snapshot server-side (runtime + your agent static config — plugins, skills, settings, Codex/OpenCode config) and pins it into project config as box.image, so later creates boot in seconds.

# one-off — bakes the base snapshot (~7 min for container, ~1 min for linux-vm)
agentbox prepare --provider daytona

The default container base is built from the Dockerfile, so it needs nothing published and works on any account.

A linux-vm base is instead baked from the prebuilt box image AgentBox publishes, which is why it's fast — Daytona can only build a VM snapshot from a published image, never from a Dockerfile. One case has no published image to boot, and falls back to a container snapshot with a warning rather than failing:

  • A locally modified Dockerfile.box — i.e. you're developing on the AgentBox repo itself. Point box.daytonaVmBaseImage at an image you've published to bake a VM anyway. It's also the knob for a private registry mirror.

An agent setting like claude.install: npm no longer forces the container fallback: the published base is agentless, so there is one image per build context and the setting reaches the derived agent tier below instead.

Agents are a separate tier

The base carries no agent. Add one as its own snapshot on top of it:

agentbox prepare --provider daytona --agents claude

How that derives depends on the class the base was baked as — a snapshot's class is immutable, so the variant always matches its base rather than box.daytonaClass:

  • container — the agent recipe is appended to the same Dockerfile build. Daytona's builder serves every layer below it from cache, so a variant takes about a minute against the base's several.
  • linux-vm — the base snapshot is booted, the agent installed, and the result cold-snapshotted.

Each agent set gets its own record, so baking --agents codex later does not invalidate the claude one, and each rebake deletes only the snapshot it replaces.

Skipping this is fine: a box whose agent isn't baked installs it on first use (~30–60s), and the result is identical — the bake and the on-demand install run the same recipe.

When you upgrade AgentBox, create --provider daytona notices if the new install would bake a different snapshot (the comparison is checksum-based on the baked files — CLI version strings on their own don't count) and offers to rebake inline; with -y or non-TTY it instead warns loudly and boots on the existing snapshot. agentbox daytona login also nudges you toward agentbox prepare --provider daytona on the first successful login.

Sizing (bake-time)

Daytona resources are fixed at snapshot-bake time — the SDK rejects custom resources on the snapshot-resume path, so --size on create doesn't resize a snapshot-booted box. Bake the size you want with agentbox prepare --provider daytona --size <cpu-memory-disk> (GB, e.g. 4-8-20), or pin it with box.sizeDaytona / box.size:

agentbox prepare --provider daytona --size 4-8-20 --force

Every bake sends an explicit size — the default is 2 vCPU / 4 GB / 8 GB disk. Leaving it to Daytona is not an option: a snapshot created with no resources takes Daytona's own 1 vCPU / 1 GB / 3 GB default, and because resources are rejected on the snapshot-resume path, every box booted from that snapshot stays that small for its whole life.

Your Daytona plan caps resources per sandbox, and a bigger ask is refused at bake time rather than silently clamped:

Disk request 20GB exceeds maximum allowed per sandbox (10GB).

On the free tier that makes 4-8-10 the practical maximum; email support@daytona.io to raise it. The 10 GB disk is usually what binds first on a large monorepo — the box image, an in-box pnpm install, and any containers the box runs itself all share it.

The snapshot name carries a size suffix (agentbox-base-<sha>-4-8-20), so re-sized bakes don't collide. If you later create --provider daytona --size 2-4-8 against a snapshot baked at a different size, the box still boots — AgentBox warns loudly that the size is fixed at bake time and points you at prepare --provider daytona --size 2-4-8 --force. Re-running prepare with the same size skips the rebuild. --size (and box.sizeDaytona / box.daytonaClass) travel with the bake request, so a bake through a control box uses the size you ask for, falling back to the control box's own pins when you omit the flag.

See CLI commands for all flags.

HEADS UP

Without prepare, every first box in a new project eats a ~7-minute cold Dockerfile build on Daytona (Playwright + Chromium). Run prepare once.

The base snapshot is shared org-wide and holds only runtime + agent config. A later project setup snapshot captured with agentbox checkpoint create also includes /workspace. See checkpoints & pausing.

Workspace seeding

Docker bind-mounts your .git/; Daytona can't, so each box is seeded from a host git clone plus your uncommitted and untracked files. Booting from a checkpoint skips the seed entirely. See teleport a project for how files reach the box.

WHY

git push from inside a Daytona box works without your SSH keys ever entering the sandbox — pushes tunnel back through the host relay. See sync & git.

Credentials & resync

Agent static config is baked into the snapshot at prepare time. Renewable tokens (Claude .credentials.json, Codex/OpenCode auth.json) are kept separate so they refresh without republishing the snapshot.

Where those tokens live depends on the class. A container box mounts them from a shared per-org volume, so one re-upload reaches every box. A linux-vm box can't — Daytona VMs silently ignore volume mounts — so each box gets its own copy uploaded at create time (the same approach Hetzner uses). The practical difference: on linux-vm, refreshing credentials affects boxes created after the refresh; already-running boxes keep the copy they booted with.

After re-authing an agent on the host, run agentbox daytona resync to re-upload the tokens.

# re-upload all agent credentials after a host re-auth
agentbox daytona resync

See run an agent for logging agents in on the host first, and CLI commands for all flags.

Preview URLs

Cloud boxes run the same @agentbox/relay in box mode, reached over preview URLs:

  • Signed — token embedded in the URL; a browser attaches by click. Used by agentbox url and agentbox screen.
  • Header-token — used by programmatic clients (the poller, cp/upload helpers).
  • Per-service — every services.*.expose.port in agentbox.yaml gets its own URL, alongside the WebProxy URL on port 8080.
# open / print the box's web preview URL
agentbox url
# the noVNC desktop (port 6080)
agentbox screen

TIP

AgentBox gives the host browser and the in-box agent symmetric https://<box-name>.localhost URLs via Portless, so a URL doesn't change depending on which side you're on. See web apps & tunnels and browser & screen.

Checkpoints & snapshots

Cloud checkpoints map to Daytona snapshots, each paired with a local host manifest. Capture takes about two seconds.

THE BOX REBOOTS

Daytona can only capture a snapshot while the sandbox is stopped, so agentbox checkpoint create stops the box, captures, and starts it again — then reconnects it. On-disk state survives; anything running (your agent's tmux session, a dev server) does not. AgentBox asks you to confirm first; pass -y to skip the prompt.

# capture /workspace state (deps installed, DB seeded, …) and make it the default
agentbox checkpoint create --set-default

--set-default writes box.defaultCheckpointDaytona, a per-provider key so Docker creates in the same project don't pick up a snapshot they can't resolve. Booting from a snapshot skips workspace seeding entirely — cold create is seconds.

# boot a fresh box straight from a saved snapshot (no reseed)
agentbox create --provider daytona --checkpoint setup

Two differences from Docker: there is no --merged (Daytona snapshots are flattened by construction) and no --replace (deletes are async — checkpoint rm then recreate). Full mechanics live in checkpoints & pausing.

Specs

Spec
Base imageDaytona snapshot baked from Dockerfile.box
Build methodServer-side snapshot via agentbox prepare --provider daytona (~1 min for linux-vm from the published image; ~7 min for container from the Dockerfile); no first-create auto-build
Docker-in-DockerYes (CAP_SYS_ADMIN; dockerd at create + start)
SSHNone — in-box bridge relay long-polled by the host (SSH-token attach for interactive sessions)
Archx86_64 (amd64)
Live snapshots~2 s filesystem capture; the box stops and reboots for it
Pauselinux-vm: true VM freeze (CPU + memory, running processes survive). container: archive to cold storage — no quota while archived, slower first resume
IdlePaused after 25 min idle (box.daytonaTimeoutMs), by the host — Daytona's own idle timer never fires while the relay is polling the box; held open while an agent is working
Preview URLSigned CloudFront https://{port}-{token}.proxy.daytona.work (1h TTL, up to 24h via --ttl)

Caveats

  • Size is fixed at bake time — snapshot-based creates inherit the snapshot's baked resources; use agentbox prepare --provider daytona --size 4-8-20 to change them (a create --size that differs just prints a warning).
  • No base image auto-buildprepare --provider daytona is required, unlike Docker.
  • No live statsagentbox top and dashboard render for cloud CPU/mem and no live attach pane.
  • Destroy lag in the dashboard — the resource is gone immediately, but the Daytona web UI lags ~30s (cosmetic).
  • download.env|config|claude not implemented for clouddownload.workspace works.
# find and clean up Daytona sandboxes AgentBox no longer tracks
agentbox prune --provider daytona

Every command honors box.provider, so once a project pins Daytona the whole CLI routes there. Flag-level detail is in the CLI reference; the per-provider config keys (box.imageDaytona, box.sizeDaytona, box.defaultCheckpointDaytona, box.bundleDepth, box.provider) are in configuration.

On this page