Skip to content
BeeuniBeeuni
English
Esc
↑↓navigate↵open⌘Jpreview
On this page

Runtime & sandbox

Sandbox lifecycle, injected environment, token families, and the image a session boots from.

Each session runs in its own isolated sandbox. This page is the reference for the sandbox lifecycle, the environment Beeuni injects at boot, the token families, and the sandbox image itself. For the session concept, see Sessions.

Sandbox lifecycle

A session row carries a status. The enum defines queued, branching, provisioning, running, stopped, failed, completed, but Beeuni only writes 4 of them.

Status Set when
provisioning At session create. Beeuni creates the session branch and requests the sandbox.
running Once the sandbox is live and reachable.
stopped On explicit stop, or by the idle sweep that hibernates inactive sandboxes.
failed If provisioning fails.

queued, branching, and completed exist in the enum but stay dead in the session flow. Do not treat them as live states.

The sandbox itself carries a separate status in its own row, with its own enum.

Status Set when
provisioning The provider boots the sandbox.
active The provider confirms the sandbox is live.
stopped Explicit stop, idle auto-stop, or mid-restart.
error The provider reports a boot or runtime failure.
archived Terminal. You deleted the session and the provider destroyed the sandbox, not paused it.

Beeuni does not cap how many sessions run at once, per account or per project. Running sessions bill compute; an account out of credit gets 402 on create.

Branch model

  • The session branch is named after the session id (a UUID). BEEUNI_SESSION_ID and BEEUNI_BRANCH_NAME carry the same value.
  • Beeuni cuts the branch from base_ref, which defaults to the project’s default branch, at session-create time.
  • Triggers create their session branch the same way an interactive session does.
  • Nothing writes the default branch directly. Only a merged change request does.

Reconcile a session branch

Use Ask Agent: Sync Branch & Reload from the session command palette when the base branch changed. The agent inspects the session branch, preserves local work, fetches the latest base_ref, resolves conflicts, runs the relevant tests, and commits the reconciliation. Beeuni does not choose one side of a conflict or reset the working tree.

The agent finishes with beeuni sessions reload "$BEEUNI_SESSION_ID" --project "$BEEUNI_PROJECT_ID" --no-repo --force --yes. --no-repo is required because the agent already reconciled the branch. The reload replaces the runtime after the replacement becomes healthy. It ends the current turn, so send continue after the runtime returns.

The session header reports each server-confirmed reload phase in real time. A web reload checks the session, compiles the agent config, applies and validates the runtime replacement, then confirms the active config. It does not refresh the repository. The CLI can refresh the repository unless you pass --no-repo.

Config convergence

Every session uses the configuration from its base branch. Push changes to that branch, then reload the session. Configuration updates wait until the active turn finishes. There is no separate Config Releases feature flag.

Use Reload config or beeuni sessions reload <session id> to apply the current configuration. If loading fails, check the session’s error details and correct the project configuration.

/workspace is where you edit, the base branch is what runs

A session ALWAYS runs the base branch’s current config. There is no per-session config mode.

/workspace is your editable checkout. Read the config there, change it there — and the change reaches the running session once it is pushed to the base branch, after which the normal convergence picks it up. An edit that is only in /workspace changes nothing about how the session behaves, and the running agent is told so: its instructions name the commit its config comes from and say that /workspace may be behind it.

The release copy is read-only, so an edit to the wrong copy fails with a permission error instead of silently doing nothing.

When the configuration no longer declares a session’s agent

A session is created with an agent. If a later commit removes or renames that agent, the session moves to the project’s default agent — once, and only when the session’s owner may use that agent. Beeuni records the move in the audit log and states it in the running agent’s instructions, so the session says what happened.

If the owner may not use the default agent, or the project declares no default, the session keeps no agent and no agent access. It still boots, and it reports the reason. Declare the agent again, set a default agent for the project, or ask a project manager for access to the default agent.

What the session header shows

State Condition Header
Current Not stale, no fallback Nothing
Update available stale: true The update badge, with Reload config
Fallback fallback_reason set A red chip: Config failed to load

A reload that ends on a fallback reports an error, not a success.

Reload config

Reload config — and beeuni sessions reload <session id> — does two things in one step, and names what happened to each:

  1. It moves the running session onto the base branch’s current agents, skills, and tools.
  2. It fast-forwards the /workspace checkout, so the files you read there match the config the session runs.

The checkout pull is fast-forward only, on the session’s own branch, so it discards nothing. Pass --no-repo on the CLI to skip it. To bring the CODE of base_ref into the session branch, use Ask agent to sync.

Try a config change before it merges

Injected environment

Beeuni injects these variables at boot. Only a project secret explicitly configured for runtime delivery enters the sandbox. Connector and model-provider credentials stay on the Beeuni server.

Variable What
BEEUNI_PROJECT_ID UUID of this project.
BEEUNI_SESSION_ID UUID of this session. Also the branch name.
BEEUNI_BRANCH_NAME Same value as BEEUNI_SESSION_ID.
BEEUNI_REPO_URL Clone URL for the project repo.
BEEUNI_DEFAULT_BRANCH The project’s default branch.
BEEUNI_BASE_REF The ref this session branched from.
BEEUNI_API_URL The platform API base (.../v1).
BEEUNI_AGENT_NAME The agent the session was created with.
BEEUNI_MODEL The model to run, when set. BEEUNI_OPENCODE_MODEL carries the same value for daemons built before this name existed.
BEEUNI_LLM_BASE_URL Beeuni LLM-gateway base URL. The gateway resolves provider credentials server-side.
BEEUNI_TOKEN The session-bound Beeuni credential. See below.

Beeuni does not inject BEEUNI_WORKSPACE. The image bakes in /workspace and no per-session step sets it. Beeuni does not inject a git token either — the daemon fetches a short-lived clone credential when it needs one; see Pushing from a session below. Beeuni rejects a user secret named with the BEEUNI_* prefix, because it reserves that prefix for platform variables.

Session credential

Beeuni has external tokens you create yourself and one credential inside each sandbox.

External tokens

A personal access token (PAT, prefixed beeuni_pat_) or a service account (prefixed beeuni_sa_) authenticates calls to the Beeuni API, the SDK, and the CLI from outside a sandbox. See Authentication for PAT scope, service-account setup, and how to choose between them.

In-sandbox token

BEEUNI_TOKEN is minted when Beeuni starts the session environment. It is bound to the launching user, project, session, and agent grant. Each API route still applies its own capability check.

Pushing from a session

No upstream Git token enters the sandbox. git push origin HEAD sends commits to the session branch. Landing on the default branch requires a merged change request.

The sandbox image

Your Dockerfile defines the base environment. Beeuni provides the session tools and dashboard connection.

Declare a template

Reference your Dockerfile as a named template under sandbox.templates in beeuni.yaml.

sandbox:
  templates:
    - slug: dev
      name: Dev box
      dockerfile: Dockerfile.dev
  default: dev

Set exactly one of dockerfile or image on each entry. Dockerfile paths must stay inside the repository. Set default to the template slug your sessions should use; omit it to use the platform default image. Older projects on beeuni.toml follow the same fields — see legacy beeuni.toml. Full field list: manifest reference.

Constraints

Rule Why
Don’t set ENTRYPOINT or CMD. Beeuni overrides both to start the daemon.
Don’t claim port 8000. Reserved for the daemon’s reverse proxy. Run dev servers on other ports.
FROM a Debian or Ubuntu base. The runtime layer runs apt-get. Alpine, Fedora, and Arch fail the build.
Don’t run apt-get clean without rm -rf /var/lib/apt/lists/*. The runtime layer re-runs apt-get update; a broken cache breaks the build.
Don’t bake credentials into the image. Declare the name in env: and set the value as a project secret. Beeuni injects it at session start.

Hardware spec

cpu, memory, and disk on a template entry set the sandbox size. All three are optional; an omitted field uses the platform default: 2 vCPU, 4 GiB memory, 20 GiB disk.

sandbox:
  templates:
    - slug: big
      image: ubuntu:24.04
      cpu: 4
      memory: 8
      disk: 50

cpu takes 1–32 cores, memory takes 1–128 GiB, and disk takes 1–500 GiB. Beeuni clamps any value above these limits down to the limit. Beeuni does not support GPUs; a gpu key on a template produces a warning, not an error.

The spec is part of the template’s snapshot, not a per-session setting. Changing it rebuilds the snapshot and applies to the next session. The current session keeps its already-booted spec.

Docker in the sandbox

Set container_runtime: true on a template to run Docker inside its sandboxes: bridge and user-defined networks, the overlayfs storage driver, and NAT egress. Local stacks such as supabase start and docker compose work as they do on a laptop.

sandbox:
  templates:
    - slug: dev
      dockerfile: .beeuni/Dockerfile.dev
      container_runtime: true

Ports and preview URLs

The daemon listens on port 8000 and proxies any other port your app uses inside the sandbox. Only port 8000 itself is blocked from the proxy.

The dashboard reaches a sandbox port two ways:

  • Path-based: https://<api-host>/v1/p/<sandbox-id>/<port>/.... This is the default form and the only one that supports WebSocket upgrades.
  • Subdomain-based: https://p<port>-<sandbox-id>.<api-host>/.... Use this form for apps that need root-relative paths or cookies, such as a Next.js or Vite dev server. WebSocket upgrades don’t work on this form yet.

The preview proxy strips X-Frame-Options and any frame-ancestors policy. A session can embed your app’s preview in an iframe without any config on your side.

A session’s preview can also be shared through a public link, in view-only or interactive mode. Public share links block ports 22, 4096, 8000, and the static file-share port.

Snapshot rebuilds

Changes to the image or environment settings rebuild the environment for subsequent sessions. Unchanged settings reuse the existing environment image. The first session that needs a rebuild shows “preparing image”; later sessions reuse that build.

Editing the Dockerfile inside a session takes effect on the next session, not the current one. The edit reaches main only once its change request merges.

Was this page helpful?