Skip to main content
Fabro separates environments from sandboxes:
  • An environment is reusable desired configuration: provider, image, resources, network, lifecycle, labels, and environment variables.
  • A sandbox is the concrete runtime instance Fabro creates for a run from the selected environment.
Older pre-v1.0 config files that still use [run.sandbox] are temporarily auto-migrated when Fabro loads them from disk. Fabro writes a sibling *.legacy-sandbox-migration.bak file, rewrites the config to [run.environment] plus an environment definition, and then continues startup.Similarly, [environments.*] tables in the server’s active settings.toml are auto-migrated on startup. Existing sibling environments/*.toml files are then treated as a legacy import source: Fabro imports missing environment IDs into SQLite once and renames the directory to environments.imported-<timestamp>.bak.These compatibility rewrites only handle direct field mappings. Unsupported legacy fields fail with a migration message that lists the keys to edit manually. The rewrite paths will be removed before v1.0.
Runs select environments by slug:
workflow.toml
Server-managed environments are stored in the server SQLite database. Manage them through the web UI or the /api/v1/environments REST API. Install seeds default as an ordinary persisted environment; users can replace or delete it. local is reserved, synthetic, and unpersisted: it appears only when the local sandbox provider is enabled, and it cannot be created, replaced, or deleted through the environments API. Workflow and project TOML can additionally define [environments.<slug>] catalog entries that merge with the server catalog through the normal settings precedence.

Defining Server Environments

Create server-managed environments through the REST API. Stored environments use inline Dockerfile content; local Dockerfile paths are rejected by the API because the server cannot safely resolve client-side paths.
POST /api/v1/environments
Server-managed local-provider environments can also set cwd, an optional runtime command working directory:
POST /api/v1/environments
cwd is owned by the server environment and is only honored by the local provider. It is not a replacement for run.working_dir. Docker and Daytona ignore cwd and report a preflight warning because those clone-based providers own their workspace layout. Workflow, project, user, and direct-run [environments.<slug>] catalogs cannot set cwd; configure it in the server-managed environment through the environments API. The same fields nest under [environments.<slug>] when defined in workflow or project TOML instead:
workflow.toml
Run-level overrides are sparse and apply only to the selected environment:
workflow.toml
env and labels merge by key.

Environment value interpolation

Environment env values can mix literal text with {{ vars.NAME }}, {{ env.NAME }}, and {{ secrets.NAME }} tokens:
workflow.toml
Server-managed variables resolve when the run is created. Worker environment variables and token secrets resolve immediately before the sandbox starts, so resolved secret values are not persisted in the run definition. A missing or non-token secret fails closed. For backward compatibility, a value containing only missing {{ env.* }} references is passed through in source form.

Selecting an environment from the CLI

Use --environment with an environment slug:
--preserve-sandbox still controls the concrete runtime instance lifecycle for a run. Runtime commands such as fabro sandbox ssh keep the word “sandbox” because they operate on an already-created runtime instance.

Seeded Environments

Install seeds a default environment into SQLite. It is a normal persisted environment, so deleting it removes the default run target until you recreate it. The standard Docker default is:
GET /api/v1/environments/default
local is not stored in SQLite. It is synthesized at runtime when the local sandbox provider is enabled.

Provider mappings

Local

local runs tools directly in the resolved working directory. It offers no filesystem or network isolation, so use it only for trusted workflows. Create a server-managed local-provider environment through the environments API when you need a host cwd. When cwd is set, local runs execute commands from that absolute server-side path. When it is unset, Fabro keeps same-host compatibility by using the submitted source directory only if that path exists on the server. If neither is available, the run fails before execution with a remediation to configure cwd. Fabro hard-errors if a local environment asks for blocked or CIDR-restricted networking because the provider cannot enforce it.

Docker

Docker runs tools inside a container created from image.docker. Docker is the built-in default provider.
workflow.toml
Docker and Daytona are clone-based providers. When a run has a GitHub origin, Fabro clones it into the provider workspace. Set [run.clone] enabled = false to start with an empty workspace. Docker and Daytona ignore cwd; use the provider-owned workspace layout and run.working_dir for repository-relative commands. The image must provide /bin/bash; Fabro evaluates every sandbox command with it and has no sh fallback. Commands run in a non-login shell, so login profiles (/etc/profile.d/*.sh, ~/.bash_profile, and nvm/rbenv/sdkman initializers) are not sourced — put anything they set into the Dockerfile’s ENV instead. Fabro verifies Bash during initialization and again on resume, and fails with remediation rather than reporting the sandbox ready.

Daytona

Daytona runs tools in a cloud sandbox. Without image.dockerfile, Fabro uses Daytona’s built-in daytona-medium snapshot. With image.dockerfile, Fabro computes a deterministic internal snapshot name from the Dockerfile, resource hints, a single-tenant scope, and the Daytona API key.
workflow.toml