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.

By default a Daytona box is a Linux VM, which means agentbox pause genuinely freezes it — 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.

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.

linux-vm (default)container
agentbox pausefreezes CPU + memory — running processes and tmux sessions survivecold storage (filesystem only)
Base bake~1 min~7 min
Checkpoint capture~2 s~2 s
Regionus-east-1 onlyany (us, eu, …)

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. If you need EU data residency or lower EU latency, set box.daytonaClass: container and you keep today's behavior (and your choice of region via 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, the agents, tmux — 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 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 (~1 min for linux-vm, ~7 min for container)
agentbox prepare --provider daytona

A linux-vm base is baked from the prebuilt box image AgentBox publishes, so it's fast — Daytona can only build a VM snapshot from a published image, never from a Dockerfile. Two cases have no published image to boot, and both fall back to a container snapshot with a warning rather than failing:

  • box.claudeInstall: npm — only the default (native) image is published.
  • 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.

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

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.

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