Files
Colton QiandClaude 5ed0137859 Release 0.1.1
Strengthen sandbox isolation and authentication, make all five engines work
through the bundled installer, and preserve conversations across sandbox and
service restarts. Add team login and single-container deployment, with upgrade
instructions for replacing existing 0.1.0 sandboxes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-26 19:09:28 -07:00

31 KiB
Raw Permalink Blame History

Deploy AstraBox

AstraBox is self-hosted. You can run the whole service on one Docker host, connect it to OpenSandbox on Kubernetes, or use an OpenSandbox service that your organization already operates. The maintained single-host deployment starts the web console, API, data stores, model and messaging gateways, and the local sandbox service. Agent tasks run in isolated sandboxes.

AstraBox deployment options

Choose where Agent sandboxes run

Deployment Best for Where sandboxes run
One Docker host Evaluation, development, and a small trusted team Separate containers on the host Docker daemon
Kubernetes with OpenSandbox Multiple nodes, prewarmed sandboxes, snapshots, and cluster controls Sandbox Pods created by OpenSandbox
An existing OpenSandbox service Organizations that operate sandbox infrastructure separately The container runtime configured for that service

The maintained local deployment listens on loopback only, and has no authentication until you turn on team login. Configure team login, TLS, and a trusted ingress before making AstraBox reachable from another network.

For Kubernetes and external-service settings, see the OpenSandbox deployment guide.

Run on one Docker host

The stack starts the following components:

Component Purpose
AstraBox API and console Create and use Agents, Assistants, Sessions, and triggers
PostgreSQL Store AstraBox and LiteLLM data
LiteLLM Route model requests and discover available models
Messaging gateway Connect Agents to messaging platforms
OpenSandbox Create and manage local sandbox containers
Casdoor, with team login on Sign people in to the console

Treat the server container as a privileged host service: it controls the mounted Docker daemon.

Docker requirements

Requirement Why
Docker Engine 26.0 or later (Engine API 1.45) Persistent workspaces reach each sandbox through a mount of a sub-directory of a Docker volume (VolumeOptions.Subpath), which Engine API 1.45 added. Everything else the stack uses is older.
Docker Compose plugin 2.17.0 or later containers/compose.yaml restarts the server when a sandbox edge is recreated (depends_on with restart: true), which Compose 2.17.0 introduced.

The installer and the server both check the daemon and refuse an older one, naming the version they found; the server checks at every start, so upgrading the host never leaves it running on an engine it does not support.

The sandbox network boundary

Each sandbox is a container on Docker's default bridge network, paired with an OpenSandbox egress sidecar that enforces its Environment's networking. The stack keeps the platform off that network:

  • The server publishes only the console, on 127.0.0.1. PostgreSQL and Redis publish only loopback development ports.
  • Two edge containers, sandbox-edge and sandbox-dns-edge, have their own addresses on the bridge. They forward only the model route, the capability-scoped callback routes and DNS to the server, over the private sandbox-edges network, which has no route off the host and which sandboxes never join.
  • The lifecycle server publishes each sandbox's execd, file/terminal and egress-API ports on the Docker bridge gateway (ASTRABOX_PUBLISH_HOST_IP, which the installer sets from docker network inspect bridge), not on the host's other interfaces. Those in-box services have no authentication: do not set ASTRABOX_PUBLISH_HOST_IP to 0.0.0.0 unless something in front of those ports authenticates every request.
  • Every sandbox's egress policy, under both Limited and Unrestricted networking, denies Docker's default bridge except sandbox-edge: other sandboxes and the bridge gateway where sandbox ports are published. The deny rules come before every allow rule, so an Environment allowlist entry that names a bridge address does not reopen it. The deny list is ASTRABOX_SANDBOX_EGRESS_DENY_CIDRS, which the server derives at startup. The egress sidecar enforces address rules only in its dns+nft mode, so the server refuses to start with ASTRABOX_SANDBOX_EGRESS_MODE=dns.
  • 169.254.0.0/16, which holds the cloud metadata service, is denied in every networking mode.
  • Sandboxes have no IPv6. The egress sidecar turns IPv6 off in the network namespace it shares with its sandbox (OpenSandbox's egress.disable_ipv6, which AstraBox sets), including when the Docker daemon enables IPv6 on the default bridge. The deny rules above are therefore IPv4 networks.

Unrestricted still allows every other destination, including the host's other addresses and your LAN. Other containers on the default bridge that are not AstraBox sandboxes, and processes on the host, can reach the published sandbox ports; the host and its other containers are inside the trust boundary.

Docker gives the two edges their bridge addresses when they start, and an edge that restarts can come back at a different one. Every sandbox keeps the addresses it was created with (its DNS upstream, its deny rules and its callback address), so the platform records them on the sandbox. When the server starts with different addresses, it removes the sandboxes created with the old ones, and a server that sees an edge move while it runs exits so that Docker restarts it. A conversation whose sandbox was removed takes a new sandbox at its next message, as after any other sandbox loss; files in the removed sandbox's workspace are kept only with the optional persistent workspace volume. Sandboxes created by AstraBox 0.1.0 carry no such record and are not removed this way. If their conversations stop receiving answers after an edge restart, remove every sandbox on the host; each conversation then continues on a new one:

docker ps -aq --filter label=opensandbox.io/id | xargs -r docker rm -f
docker ps -aq --filter label=opensandbox.io/egress-sidecar-for | xargs -r docker rm -f

Install a release

curl -fsSL https://raw.githubusercontent.com/Colton-z/AstraBox/main/scripts/install.sh | bash

The installer:

  1. checks Docker Engine 26.0 or later, the Compose plugin 2.17.0 or later (see Docker requirements), and that your user can use /var/run/docker.sock;
  2. downloads the deployment bundle of the latest release, verifies its SHA-256, and unpacks the Compose files into ~/astrabox;
  3. generates the database and login secrets in ~/astrabox/.astrabox/database-secrets, once, and keeps them afterwards;
  4. asks which model service your Agents use, and for its API key and model ID, and writes their settings;
  5. asks whether to turn on team login, which runs the bundled Casdoor login service with the stack;
  6. pulls the images published for that release, starts the stack, waits until the console page is served, and pulls the sandbox image of the seeded Claude Code Agent so that the first Session does not wait for it.

Re-run it to upgrade: it installs the latest release's Compose files, or those of the release ASTRABOX_VERSION names, sets that release as the image version, and keeps the volumes, the generated secrets, the model settings, the team-login choice, and every other line of the installation's settings file. To change the model service, answer its question again, or run it with ASTRABOX_INSTALL_MODEL_PROVIDER set; the settings it wrote for the previous service are removed.

Model services the installer configures

The bundled LiteLLM gateway serves each of these. Add further routes afterwards as described in Connect a model.

Choice Settings it writes Model name the gateway routes
Anthropic ANTHROPIC_API_KEY, ANTHROPIC_MODEL the model ID, through the claude-* route
DeepSeek ANTHROPIC_BASE_URL (DeepSeek's Anthropic endpoint), ANTHROPIC_API_KEY, ANTHROPIC_MODEL (default deepseek-flash) anthropic/<model ID>
Another Anthropic-compatible service ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_MODEL anthropic/<model ID>
An OpenAI-compatible service OPENAI_COMPATIBLE_BASE_URL, OPENAI_COMPATIBLE_API_KEY, ANTHROPIC_MODEL openai-compatible/<model ID>
None for now nothing add routes in the console under Integrated services

ANTHROPIC_MODEL is the deployment's default model: the seeded Agents use it until an Agent selects its own, and an Agent that selects a model enters the name in the last column. With ANTHROPIC_BASE_URL set, the deployment serves the default model through the gateway's anthropic/ routes. For DeepSeek it also recognises the endpoint and gives the same credential to the gateway's OpenAI-wire DeepSeek routes, which the other Agent programs use.

The openai-compatible/* route sends <model ID> to OPENAI_COMPATIBLE_BASE_URL over Chat Completions. Claude Code, the Agent program a fresh installation seeds, speaks Anthropic Messages, so LiteLLM translates between the two protocols; prefer a service's Anthropic-compatible endpoint when it publishes one.

Installer settings

Setting ASTRABOX_INSTALL_MODEL_PROVIDER and ASTRABOX_INSTALL_TEAM_LOGIN runs the installer without questions, which is what an unattended installation needs. Without a terminal, the installer keeps the current team-login choice, which is off on a new installation.

Variable Purpose
ASTRABOX_VERSION Release to install. Default: the latest release.
ASTRABOX_INSTALL_DIR Installation directory. Default: ~/astrabox.
ASTRABOX_INSTALL_BUNDLE Path of an astrabox-deploy-<version>.tar.gz downloaded elsewhere, for a host that cannot reach GitHub.
ASTRABOX_IMAGE_PREFIX Repository prefix of a registry mirror holding the published images; the component name is appended. Default: ghcr.io/colton-z/astrabox-.
ASTRABOX_INSTALL_MODEL_PROVIDER anthropic, deepseek, anthropic-compatible, openai-compatible or none.
ASTRABOX_INSTALL_MODEL_API_KEY The model service's API key.
ASTRABOX_INSTALL_MODEL_NAME The model ID the seeded Agents use. Default for DeepSeek: deepseek-flash.
ASTRABOX_INSTALL_MODEL_BASE_URL Base URL of an Anthropic-compatible or OpenAI-compatible service.
ASTRABOX_INSTALL_TEAM_LOGIN casdoor runs the bundled Casdoor login service with the stack; none runs the stack without login.
ASTRABOX_CONSOLE_ORIGIN With team login: the console's public URL, such as https://astrabox.example.com.
ASTRABOX_OIDC_ISSUER With team login: Casdoor's public URL, such as https://login.example.com. Set both URLs for browsers on other computers, or neither to sign in on this host only.
curl -fsSL https://raw.githubusercontent.com/Colton-z/AstraBox/main/scripts/install.sh \
  | ASTRABOX_INSTALL_MODEL_PROVIDER=deepseek \
    ASTRABOX_INSTALL_MODEL_API_KEY="your-deepseek-api-key" bash

Compose settings live in ~/astrabox/containers/.env, which the installer keeps across upgrades. Create or edit it to change a port, a volume name or any other Compose value, then re-run the installer:

printf '%s\n' "ASTRABOX_SERVER_HOST_PORT='9000'" >> ~/astrabox/containers/.env

Manage the installed stack from that directory with the ordinary Compose commands, docker compose ps, docker compose logs -f server and docker compose down. With team login on, they include Casdoor.

Turn on team login

curl -fsSL https://raw.githubusercontent.com/Colton-z/AstraBox/main/scripts/install.sh \
  | ASTRABOX_INSTALL_TEAM_LOGIN=casdoor \
    ASTRABOX_CONSOLE_ORIGIN=https://astrabox.example.com \
    ASTRABOX_OIDC_ISSUER=https://login.example.com bash

The installer adds the SSO overlay, containers/compose.sso.yaml, to the COMPOSE_FILE setting in ~/astrabox/containers/.env, so the stack and every docker compose command in ~/astrabox/containers run Casdoor with AstraBox. Casdoor listens on 127.0.0.1:8087. With the two public URLs, the installer also writes the callback URL and the Host allowlist the server needs; put both loopback ports behind an HTTPS proxy as described in Put the login flow behind a proxy. Leave both URLs out to sign in on this host only.

When it finishes, the installer prints where the generated passwords are kept: that of the admin account people sign in to AstraBox with, and that of Casdoor's own administrator, built-in/admin. AstraBox accepts only accounts of the bundled astrabox organization; see Turn on the bundled login service.

Running the installer again keeps team login on. To turn it off, run it with ASTRABOX_INSTALL_TEAM_LOGIN=none. An installation with public URLs refuses until they are removed from containers/.env, so that it never serves the console without login to other computers.

Published images

Every release publishes these images, tagged with its version. The installer writes that version to the settings file as ASTRABOX_IMAGE_TAG; a deployment that names no image of its own runs <ASTRABOX_IMAGE_PREFIX><component>:<ASTRABOX_IMAGE_TAG> for its server, every Agent program's sandbox and the workspace helper.

Image Architectures
ghcr.io/colton-z/astrabox-server amd64, arm64
ghcr.io/colton-z/astrabox-sandbox-claude-code amd64, arm64
ghcr.io/colton-z/astrabox-sandbox-codex amd64, arm64
ghcr.io/colton-z/astrabox-sandbox-deepseek-harness amd64, arm64
ghcr.io/colton-z/astrabox-sandbox-hermes amd64, arm64
ghcr.io/colton-z/astrabox-sandbox-pi amd64, arm64
ghcr.io/colton-z/astrabox-workspace-mounter amd64

The workspace helper is amd64 only: it installs the mergerfs release archive built for that architecture.

Run from a clone

A checkout builds and runs its own images, astrabox/<component>:latest:

make build-agent-image

export ANTHROPIC_API_KEY="your-anthropic-api-key"
export ANTHROPIC_MODEL="your-model-name"
scripts/compose.sh up --build -d

Open http://127.0.0.1:8088.

On Linux, scripts/compose.sh detects the Docker socket's group. If detection does not work for your Docker installation, set its numeric group ID before starting the stack:

export DOCKER_GID="$(stat -c %g /var/run/docker.sock)"
scripts/compose.sh up --build -d

On macOS, use stat -f %g for the socket group, or rely on Docker Desktop's socket access.

Where conversation workspaces live

Workspace file persistence is optional. The bundled backing-medium adapter is ASTRABOX_STORAGE_PROVIDER=mounted_volume. Persistent deployments set ASTRABOX_SANDBOX_WORKSPACE_VOLUME to the backing volume's name: an existing PersistentVolumeClaim on Kubernetes, or a named volume on Docker. Workspaces occupy separate directories on that backing filesystem. The platform's mergerfs router creates fixed views outside user sandboxes; OpenSandbox mounts those views through its standard PVC or named-volume interface. Binding to the selected new or existing workspace completes before delivery to the user. The storage adapter selects the backing medium; it cannot opt out of platform routing.

An unset or empty value leaves workspace files on the sandbox's temporary filesystem; replacing that sandbox can discard those files. This setting governs workspace files, not the platform database's custody of native SessionStores. In this no-volume mode no mount helper runs, whatever ASTRABOX_WORKSPACE_MOUNTER_IMAGE names.

With an existing OpenSandbox service (ASTRABOX_SANDBOX_OPENAPI_BASE_URL), persistent workspaces require that service's Kubernetes runtime; see Connect an existing OpenSandbox service.

Configure the workspace helper

ASTRABOX_WORKSPACE_MOUNTER_IMAGE names the helper image; unset, it is the release's own ghcr.io/colton-z/astrabox-workspace-mounter:<version>. Set it to an image of your own, built with make build-workspace-mounter-image and published under an immutable tag, when you change the helper. This is a separate host-side helper, not an additional agent-runtime component.

Set ASTRABOX_WORKSPACE_STORAGE_TOPOLOGY=local only for one eligible sandbox host. Local ext4 is suitable for that topology. Multiple sandbox hosts require shared and the same remotely accessible filesystem on every eligible host; identical directory names on separate local disks are not shared storage. API server replicas alone do not change this requirement.

ASTRABOX_WORKSPACE_MOUNT_ROOT names a host-side directory for assignment views, defaulting to /var/lib/astrabox/workspace-mounts. Keep it separate from the backing workspace data. Each helper receives only its own view directory and uses bidirectional mount propagation. On Docker, configure the containing host mount as shared before enabling persistent workspaces; Docker refuses rshared propagation from an unshared source. The helper requires Linux 6.9+ on amd64, root, /dev/fuse, and privileged mount access. User sandboxes do not receive those privileges. The helper requires native mergerfs I/O passthrough and its compatible cache mode; it does not silently disable passthrough.

On Kubernetes, the platform identity needs permission to manage the helper Pods and their exec endpoint, assignment PVCs and PVs, and to list Nodes. The namespace must permit these privileged infrastructure Pods. The backing PVC remains operator-owned. Kubernetes schedules each helper; its view PV pins the sandbox to that same node. Losing a helper invalidates its existing FUSE mount and is not repaired by silently restarting it under a live sandbox. Docker's view volume is a recursive bind of the helper's view directory, so its numbered FUSE submounts are present in the consumer; a nonrecursive bind would expose the empty underlying host directories instead, which the sandbox mount check rejects. The bind is a slave copy: Docker unmounts the volume when its last container exits, and a shared copy would carry that unmount back to the helper's views on the host. Docker only mounts such a volume for a container that uses it by name, so the sandbox receives its workspace through Docker's volume sub-path mount, one reason the stack needs Docker Engine 26.0 (Docker requirements).

Each helper records, from the moment it is created, the assignment it serves, the sandbox backend and the AstraBox installation. The expiration watcher releases a view once its sandbox is confirmed gone, and also releases a view no sandbox ever took: when a create fails or provisioning stops part way, the view is removed ten minutes after its helper was created if no sandbox of the installation carries its assignment. A view a container or Pod still mounts is never removed.

What the medium has to support

For AWS EFS, use the aws_efs storage provider. It verifies the configured EFS CSI claim; the platform router is unchanged.

A workspace is a working directory, not a document store, and the code that prepares one uses these operations. A medium that lacks any of them is not a candidate, however convenient its capacity:

Operation Used by
rename onto an existing path publishing each file of a plugin-repo cache, so a sibling conversation never reads half of one
chmod (mode preservation) plugin scripts committed 100755; without it the conversation runtime has executables it can neither run nor chmod, because the cache is root-owned
flock serialising concurrent clones into one Agent's shared cache
symbolic links the conversation's visible /workspace is a symlink onto its physical directory, and the mount check resolves through it
ReadWriteMany several boxes mount the claim at once, and one Agent's box carries several conversations
Medium Verdict
POSIX network filesystems, such as NFS, EFS and CephFS Must support the operations above, have a filesystem type recognized by the helper, and provide a claim that binds before a consumer starts. Do not serve NFS from the same node that mounts it.
Cluster default StorageClass Depends what it provisions. Confirm it is POSIX and not node-local before relying on it.
Object storage through a FUSE driver Use only after proving every operation above. Mountpoint for Amazon S3 does not qualify.

In shared topology, the helper recognizes nfs, nfs4, cifs, smb3, ceph, fuse.ceph, glusterfs, fuse.glusterfs, lustre, gpfs, beegfs, and fuse.juicefs. Other filesystem types are rejected, even when a driver advertises POSIX support. Recognition does not replace checking the required operations on the chosen deployment.

Mountpoint for Amazon S3 documents that file rename is unavailable on general-purpose buckets, directory rename is unavailable on every bucket type, and chmod, lockf, hard links, and symbolic links are unsupported. These limitations conflict with the workspace operations above. See its file-system behavior.

Object storage still has a place in this system — snapshots, exports, backups are whole objects written once. A live working directory is not.

OpenSandbox also defines an ossfs volume type, but AstraBox does not select it. When workspace persistence is configured, every sandbox creation path, including prepared capacity, uses the platform's fixed-view volume plan over the selected storage provider's backing medium. AstraBox accepts only storage providers configured for the deployment.

What the deploy checks

When enabling workspace persistence on Kubernetes, provide a bound ReadWriteMany PersistentVolumeClaim with the name in ASTRABOX_SANDBOX_WORKSPACE_VOLUME. The storage helper mounts this backing claim; OpenSandbox receives the assignment's ready view claim. AstraBox refuses runtime preparation when the configured storage provider cannot confirm the requested mount.

Connect messaging platforms

The server image already contains the pinned Satori adapters and their private connector runtime. Create a messaging-platform Deployment from the Agent page and complete the provider form. The detail page shows the callback URL or connection state and links to the provider's official developer console.

Single-server installations use the packaged connector on container loopback. A multi-replica installation can operate one shared connector behind authenticated HTTPS. Set ASTRABOX_CHANNEL_GATEWAY_BASE_URL to that endpoint and configure the same ASTRABOX_CHANNEL_GATEWAY_TOKEN on AstraBox and the gateway. See the configuration reference in the repository for the requirements.

Run multiple platform replicas

The platform-replica deployment recipe connects multiple API hosts to shared services and signing keys. A request can reach either API replica; Kubernetes schedules the sandbox independently. Adding API replicas does not make local workspace disks shared or turn a single OpenSandbox lifecycle service into a highly available service.

Build sandbox images

An Environment connects an Agent to an Agent program and a compatible sandbox image. The image supplies the operating system, CPU architecture, Agent program, commands, and language runtimes available to the Agent.

Build a custom image when every Session needs additional software. Start from the corresponding bundled sandbox image, install and pin the dependencies, and then select the custom image in the Environment. Publish immutable image tags for production deployments.

Agent programs, accounts, and control processes required by a sandbox must already be present when the sandbox starts. Do not depend on a per-Session setup script: a prewarmed sandbox can exist before the Session that uses it.

Bundled sandbox images expose /workspace as the Session workspace. The Session's Files view reads and writes the same directory. A custom image must make its configured working directory writable by the Agent program. See the container reference for the image requirements.

Save and restore data

The maintained Compose deployment stores service data separately from Agent sandboxes:

Location Contents
astrabox-postgres volume AstraBox and LiteLLM databases
astrabox-state volume /data state, generated keys, and local OpenSandbox metadata
.astrabox/database-secrets Generated database credentials and optional bundled-SSO credentials, under the installation directory (~/astrabox) or the checkout
Optional workspace volume Agent and Assistant workspace files, independently of any sandbox

Session messages and native session state are stored in the AstraBox database. Workspace files live on the workspace volume when configured, so terminating or replacing a sandbox does not remove them; a replacement box mounts the same stored workspace. Without a workspace volume, files depend on the sandbox or a retained filesystem snapshot. OpenSandbox's ordinary pause snapshots preserve the root filesystem, not process memory; they are not the durability mechanism for volume-backed workspace files or database-backed native session state.

Back up the following as one recovery set:

  • astrabox-postgres;
  • astrabox-state;
  • .astrabox/database-secrets;
  • the local vault key or KMS key required to decrypt saved credentials;
  • the workspace volume or its backing filesystem, when configured;
  • external LiteLLM storage, when configured.

The default local Credential Vault key comes from ASTRABOX_VAULT_MASTER_KEY or /data/vault.key. Encrypted credentials cannot be restored without the same key.

Make AstraBox available to a team

AstraBox supports OIDC, trusted identity headers from an authenticated gateway, and JWT verification. An installation configures one of them through its settings file; Set up team login lists the settings. The bundled SSO overlay, which starts Casdoor for evaluation, runs from a clone:

scripts/compose.sh -f containers/compose.sso.yaml up -d

The bundled Casdoor applications use /static/astrabox-mark.svg for their login logo. The overlay mounts the repository's existing brand asset into Casdoor's static directory, so loading the logo requires no external CDN. Casdoor seeds application data only at initialization; for an existing Casdoor database, set the application's Logo field to that path in its application settings. The AWS testbed reconciles the console application's Logo through Casdoor's API as part of deployment.

At the team ingress, terminate TLS, add the public hostname to ASTRABOX_ALLOWED_HOSTS, prevent direct access to the AstraBox service port, and use the same login-cookie signing secret on every replica. See Set up team login for the supported identity configurations.

Plan capacity for prepared sandboxes

Every Agent with prewarming on keeps one idle prepared sandbox so that its next conversation starts in about two seconds instead of starting a sandbox. New Agents have prewarming on wherever ASTRABOX_AGENT_PREWARM_REDIS_URL is set, which every bundled Compose deployment and the all-in-one container do; there, the two Agents a fresh installation creates have it on as well. The sandbox is held for as long as prewarming stays on and the Agent and its Environment are enabled; after a conversation claims it, AstraBox prepares a replacement. AstraBox does not cap the number of prepared sandboxes, so size the deployment for the Agents you keep, or turn prewarming off for Agents that do not need a fast first conversation.

What an idle prepared sandbox uses depends on the engine that the Agent's Environment runs:

Engine Idle memory of one prepared sandbox
Claude Code About 0.5 GiB: 490–536 MiB for the sandbox container on a Docker host
pi About 0.45 GiB: 450 MiB for the sandbox container on a Docker host
DeepSeek Harness 921–940 MiB of anonymous memory per sandbox Pod on Kubernetes
Other engines, including Codex 390–650 MiB of anonymous memory per sandbox Pod on Kubernetes

On a Docker host each sandbox's egress sidecar adds about 60 MiB, and an idle sandbox uses 2–5% of one CPU.

Where sandboxes run How that capacity is accounted for
One Docker host Nothing is reserved: Docker sets aside nothing for an idle container, so the cost is the memory above plus the sidecar. About 20 Claude Code Agents use roughly 11 GiB of the host's memory while idle.
Kubernetes with OpenSandbox Each sandbox requests 200m CPU and 768 MiB of memory, and the scheduler places sandboxes by these requests. A DeepSeek Harness sandbox uses more memory than it requests, so plan node memory from actual use, not from requests. For example, 19 sandboxes request 3.8 CPUs and 14.25 GiB, about all that a node with 4 vCPUs and 16 GiB leaves allocatable to Pods, yet 19 idle DeepSeek Harness sandboxes use about 17 GiB.
An existing OpenSandbox service The same request per sandbox: 200m CPU and 768 MiB. Whether it is reserved depends on that service's runtime, as in the two rows above; plan memory from actual use either way.

Each sandbox may grow to 4 CPUs (on Docker, at most the host's CPU count) and 4 GiB of memory while it works; the figures above are what idle capacity takes. To turn prewarming off for an Agent, clear Keep a sandbox ready in its Runtime and availability settings, or set "prewarm_enabled": false through the API or in an astrabox.yaml document.

Check health and sandbox recovery

AstraBox exposes separate liveness and readiness endpoints:

GET /healthz
GET /readyz

/readyz returns 503 after shutdown draining begins. Set the platform's termination grace period higher than ASTRABOX_SHUTDOWN_DRAIN_SECONDS so in-flight Agent work has time to finish.

CPU, memory, disk, and sandbox timeouts come from the selected OpenSandbox runtime and its configuration. Before relying on paused sandboxes, verify every Environment that uses them against the deployed backend:

astrabox verify-opensandbox-snapshots

Connect models, messaging platforms, and credentials

Production checklist

Before inviting users:

  • enable authentication and verify authorization for user and machine access;
  • terminate TLS at a trusted ingress and set ASTRABOX_ALLOWED_HOSTS;
  • use shared persistence and the same signing and encryption keys on every replica;
  • back up database data, state, credentials, and encryption keys together;
  • verify sandbox access to the model gateway, AstraBox callbacks, remote MCP servers, and other required destinations;
  • verify snapshot recovery for every Environment that pauses sandboxes;
  • set the required outbound network rules and sandbox permissions;
  • run a real Agent task while testing graceful shutdown;
  • collect logs, metrics, and traces with explicit access and retention rules.