Docker Runtime
worker-docker is the default worker type. It creates and manages Docker containers to execute code in isolated sandboxes.
When to use
- General-purpose sandboxed code execution
- You already have Docker installed on the host
- You want to use mature container technology
How it works
- The worker connects to the control node over gRPC.
- When an execution request arrives, the worker pulls or reuses an image and starts a container.
- Code runs inside the container with resource limits applied.
- Output is streamed back through the control plane.
For terminalResource validate/read/export operations, the worker probes file metadata via docker exec <container> python3 -c ..., so the terminal execution image must provide python3.
Prerequisites
- Docker Engine
- Network access to the control node gRPC endpoint
Starting the worker
Download the matching version of the worker-docker binary from the GitHub releases page, then run:
WORKER_CONSOLE_GRPC_TARGET=<console_grpc_target> \
WORKER_ID=<worker_id> \
WORKER_SECRET=<worker_secret> \
./onlyboxes-worker-dockerSet WORKER_CONSOLE_INSECURE=true when connecting without TLS.
Configuration file
The Worker Startup Tool in the dashboard can generate and download a ready-to-use config.toml. Set WORKER_CONFIG_FILE to use a specific file. If it is not set, the worker looks for config.toml next to the worker binary and then in the current working directory.
Environment variables take precedence over config.toml, which takes precedence over built-in defaults. TOML keys use the environment variable name without the WORKER_ prefix and in lowercase; for example, WORKER_TERMINAL_EXEC_DOCKER_IMAGE becomes terminal_exec_docker_image. Use a [labels] table for worker labels.
id = "wk_..."
secret = "..."
console_grpc_target = "console.internal:50051"
terminal_exec_docker_image = "coolfan1024/onlyboxes-runtime:default"
terminal_max_active_sessions = 0
[labels]
region = "us"See the annotated configuration template for all available keys.
Environment variables
Connection
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_CONSOLE_GRPC_TARGET | No | 127.0.0.1:50051 | Control node gRPC address |
WORKER_CONSOLE_INSECURE | No | false | Set true to allow insecure connections (non-TLS) |
WORKER_ID | Yes | Worker ID from the dashboard | |
WORKER_SECRET | Yes | One-time secret from worker creation |
Identity
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_NODE_NAME | No | Human-readable node name | |
WORKER_VERSION | No | build version | Version reported to console |
WORKER_LABELS | No | CSV labels, e.g. region=us,owner=team-a |
Docker images
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_PYTHON_EXEC_DOCKER_IMAGE | No | ghcr.io/astral-sh/uv:python3.12-bookworm-slim | Image for Python execution |
WORKER_TERMINAL_EXEC_DOCKER_IMAGE | No | coolfan1024/onlyboxes-runtime:default | Image for terminal execution |
terminalExecandterminalResourceboth rely on the terminal execution image. If that image does not includepython3, file probe operations will fail before metadata can be validated or exported.
The default terminal image is a general execution image with Python 3, Node.js 24, npm, Corepack, common shell/file utilities, lightweight document helpers, and agent-browser with Lightpanda. Use coolfan1024/onlyboxes-runtime:lobehub for LobeHub-specific sandbox tooling.
Docker network
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_DOCKER_NETWORK | No | Isolated bridge used by terminalExec and pythonExec containers |
When configured, the Worker checks the network before connecting to Console:
- If the network does not exist, the Worker creates it with the
bridgedriver andcom.docker.network.bridge.enable_icc=false, then verifies it again. - If the network already exists, its driver must be
bridgeandcom.docker.network.bridge.enable_iccmust explicitly befalse. - If Docker inspect/create fails, the network is still missing after creation, the driver does not match, or ICC is enabled, Worker startup fails. It does not register with Console or fall back to Docker's default network.
After validation succeeds, terminal container creation, IP inspection, session recovery, and pythonExec container creation all use this network. To select a specific subnet or gateway, pre-create the network as an administrator:
docker network create \
--driver bridge \
--subnet 172.28.0.0/16 \
--gateway 172.28.0.1 \
--opt com.docker.network.bridge.enable_icc=false \
onlyboxes-sandbox-customWhen unset, existing behavior is preserved: with public preview disabled, terminalExec and pythonExec use Docker's default network; with public preview enabled, only terminalExec joins the automatically managed onlyboxes-sandbox bridge while pythonExec stays on Docker's default network. End existing terminal sessions on this Worker before changing the network, because containers attached to the old network cannot be recovered through the new one.
Execution resources
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_PYTHON_EXEC_MEMORY_MIB | No | 256 | Memory limit for pythonExec containers in MiB |
WORKER_PYTHON_EXEC_CPUS | No | 1.0 | CPU limit for pythonExec containers |
WORKER_PYTHON_EXEC_MAX_PROCESSES | No | 128 | Max process / task count for pythonExec containers |
WORKER_TERMINAL_EXEC_MEMORY_MIB | No | 256 | Memory limit for terminalExec containers in MiB |
WORKER_TERMINAL_EXEC_CPUS | No | 1.0 | CPU limit for terminalExec containers |
WORKER_TERMINAL_EXEC_MAX_PROCESSES | No | 128 | Max process / task count for terminalExec containers |
Concurrency
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_ECHO_MAX_INFLIGHT | No | 4 | Max concurrent echo commands |
WORKER_PYTHON_EXEC_MAX_INFLIGHT | No | 4 | Max concurrent pythonExec commands |
WORKER_TERMINAL_EXEC_MAX_INFLIGHT | No | 4 | Max concurrent terminalExec commands |
WORKER_TERMINAL_RESOURCE_MAX_INFLIGHT | No | 4 | Max concurrent terminalResource commands |
WORKER_TERMINAL_SESSION_MAX_INFLIGHT | No | 1 | Max concurrent operations in one terminal session; shared by terminalExec and terminalResource |
WORKER_TERMINAL_MAX_ACTIVE_SESSIONS | No | 0 (unlimited) | Maximum terminal sessions managed by this worker process |
WORKER_TERMINAL_EXEC_MAX_INFLIGHT and WORKER_TERMINAL_RESOURCE_MAX_INFLIGHT independently limit their respective capabilities across the worker; there is no additional aggregate worker-wide limit. WORKER_TERMINAL_SESSION_MAX_INFLIGHT applies to one session_id and counts terminalExec and terminalResource together. A request must satisfy both its capability limit and the session limit.
WORKER_TERMINAL_MAX_ACTIVE_SESSIONS is a separate session-count limit. 0 leaves the count unlimited; a positive value counts sessions that are being created, ready, waiting for in-flight commands to drain, or undergoing Docker cleanup. Existing sessions remain usable when the limit is full, while a new session returns 429 session_capacity_exceeded. Negative or invalid values fall back to 0.
For example, with both capability limits set to 10 and the per-session limit set to 2, the worker can process up to 10 terminalExec and 10 terminalResource operations at once, while any one session can run at most two operations in total. Exceeding the per-session limit returns 409 session_busy; exhausting a capability's worker-wide concurrency returns 429 no_capacity; exhausting the session-count limit while creating a session returns 429 session_capacity_exceeded.
Terminal lease
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_TERMINAL_LEASE_MIN_SEC | No | 60 | Minimum lease duration (seconds) |
WORKER_TERMINAL_LEASE_MAX_SEC | No | 1800 | Maximum lease duration (seconds) |
WORKER_TERMINAL_LEASE_DEFAULT_SEC | No | 60 | Default lease duration (seconds) |
WORKER_TERMINAL_OUTPUT_LIMIT_BYTES | No | 1048576 | Output limit per stream (bytes) |
WORKER_TERMINAL_EXPORT_MAX_BYTES | No | 0 (unlimited) | Maximum file size in bytes for export action; 0 disables the limit |
The Worker advertises terminalLeaseRenew as an internal Console-only capability. It accepts {"session_id":"required","lease_ttl_sec":300}, extends an existing lease monotonically, resets the session lease timer, and returns the confirmed absolute expiry without executing a command. Its independent max_inflight declaration uses the configured WORKER_TERMINAL_EXEC_MAX_INFLIGHT value.
Heartbeat
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_HEARTBEAT_INTERVAL_SEC | No | 5 | Heartbeat interval (seconds) |
WORKER_HEARTBEAT_JITTER_PCT | No | 20 | Jitter percentage (0–100) |
WORKER_CALL_TIMEOUT_SEC | No | ceil(2.5 * interval) | gRPC call timeout (seconds) |
Logging
| Variable | Required | Default | Description |
|---|---|---|---|
WORKER_LOG_LEVEL | No | info | debug / info / warn / error |
WORKER_LOG_FORMAT | No | json | json / text |
WORKER_LOG_ADD_SOURCE | No | false | Include source file and line |