What the Daytona integration enables
| Feature | How it’s used |
|---|---|
| Sandboxed execution | Agent tool calls (shell commands, file edits, grep, glob) run inside a cloud VM instead of on the host |
| Snapshots | Pre-built environment images so each run starts with dependencies already installed |
| SSH access | Connect to a running sandbox for live debugging |
| Network controls | Restrict agent egress with block-all or CIDR-based allow lists |
| MCP sandbox transport | Run MCP servers inside the sandbox — e.g., Playwright for browser automation |
Prerequisites
- A
DAYTONA_API_KEYsaved in the Fabro server vault (get one from app.daytona.io) - GitHub access configured via the default
tokenstrategy or a GitHub App (required for private repository cloning and checkpoint pushing)
write:snapshots, delete:snapshots, write:sandboxes, and delete:sandboxes. Fabro validates these scopes during install, when you run fabro secret set DAYTONA_API_KEY, and in fabro doctor.
DAYTONA_API_KEY from process env or server.env; non-secret Daytona settings such as API URL or organization ID remain normal configuration.
Configuration
Select a Daytona environment in your run config TOML or via CLI flag:run.toml
run.toml
Network access control
Control outbound network access with thenetwork field. Three modes are available:
run.toml
"block" or a CIDR allow list when running untrusted or generated code to prevent agents from making arbitrary network requests.
Snapshots
Snapshots let you pre-build an environment image so each run starts with dependencies already installed rather than installing them in setup commands every time.run.toml
image.dockerfile, Fabro computes an internal snapshot name and looks up that snapshot in Daytona. If it doesn’t exist, Fabro creates it automatically and polls until it reaches Active state (up to 10 minutes). dockerfile can be inline content or { path = "..." }; paths are resolved relative to the TOML file that declares them and are bundled into run manifests. If the snapshot already exists, it’s reused immediately.
If no Dockerfile is configured, sandboxes are created from the
daytona-medium snapshot which includes standard dev tools (git, etc.). To force a new custom snapshot, change the Dockerfile text, for example by adding a comment.Private repositories
Fabro automatically clones the run’s GitHub origin into the sandbox at/home/daytona/workspace. Public repositories work without extra configuration. Private repositories require GitHub access. In token mode, Fabro uses the stored token directly. In app mode, Fabro uses short-lived Installation Access Tokens scoped to the specific repository.
Set [run.clone] enabled = false when a workflow should start with an empty Daytona workspace instead of cloning the run origin:
run.toml
SSH access
Connect to a running Daytona sandbox via SSH for live debugging:--print to print the SSH command instead of connecting, or --ttl to set the credential expiry.
To keep the sandbox alive after the run completes, pass
--preserve-sandbox to fabro run.Sandbox lifecycle
Each sandbox gets a unique timestamped name (e.g.fabro-20260307-143022-a3f2) and is created as ephemeral. By default, sandboxes are destroyed when the run finishes.
Preservation
To keep a sandbox alive for debugging:run.toml
Auto-stop
Thelifecycle.auto_stop setting tells Daytona to stop the sandbox after a period of inactivity, saving costs for preserved or long-running sandboxes:
run.toml
Server defaults
When running viafabro server start, the server config at ~/.fabro/settings.toml can set default Daytona settings for all runs. Run config TOML values override server defaults. Labels are merged — run config labels win on key collisions. The network setting uses simple override (run config replaces the server default entirely).
See Server Configuration for details.
Troubleshooting
”Failed to create Daytona sandbox”
TheDAYTONA_API_KEY vault secret is missing, invalid, or missing the required snapshot/sandbox scopes. Store it with fabro secret set DAYTONA_API_KEY ..., then run fabro doctor to verify that Daytona reports the key as valid.
If doctor reports missing scopes, regenerate the Daytona key with write:snapshots, delete:snapshots, write:sandboxes, and delete:sandboxes, then save it again with fabro secret set DAYTONA_API_KEY.
Custom snapshot did not roll
Custom Daytona snapshot names are computed from the Dockerfile, resource hints, tenant scope, and Daytona API key. To force a new custom snapshot, changeimage.dockerfile text under the selected [environments.<slug>.image].
”Timed out waiting for snapshot to become active”
Snapshot creation took longer than 10 minutes. This can happen with large Dockerfiles. Check the snapshot status in the Daytona dashboard — it may still be building. Subsequent runs will reuse the snapshot once it’s active.Git clone fails for private repositories
See Private repositories above. You need a GitHub App configured and installed on the repository’s organization or account.Stall watchdog kills the run
Long-running commands in Daytona sandboxes may trigger the 1800-second stall watchdog if they don’t produce events. For workflows with long-running operations, increase thestall_timeout in the workflow graph: