Docker 运行时

worker-docker 是默认的 worker 类型,通过创建和管理 Docker 容器来隔离执行代码。

适用场景

  • 通用的沙箱代码执行
  • 宿主机已安装 Docker
  • 希望使用成熟的容器技术

工作原理

  1. Worker 通过 gRPC 连接控制节点。
  2. 收到执行请求后,worker 拉取或复用镜像并启动容器。
  3. 代码在资源受限的容器内运行。
  4. 输出通过控制面流式返回。

对于 terminalResource 的 validate/read/export,worker 会通过 docker exec <container> python3 -c ... 探测文件元数据,因此 terminal 执行镜像必须提供 python3。

前置条件

  • Docker Engine
  • 能够访问控制节点 gRPC 端口

启动 worker

从 GitHub Releases 页面 下载对应版本的 worker-docker 二进制文件,然后运行:

WORKER_CONSOLE_GRPC_TARGET=<console_grpc_target> \
WORKER_ID=<worker_id> \
WORKER_SECRET=<worker_secret> \
./onlyboxes-worker-docker

通过非 TLS 连接时请设置 WORKER_CONSOLE_INSECURE=true。

配置文件

Dashboard 中的 Worker 启动工具可以生成并下载可直接使用的 config.toml。设置 WORKER_CONFIG_FILE 可以显式指定配置文件;未设置时,worker 会依次查找程序文件同目录和当前工作目录下的 config.toml。

配置优先级为:环境变量 > config.toml > 内置默认值。TOML 键名由环境变量名移除 WORKER_ 前缀并转换为小写得到,例如 WORKER_TERMINAL_EXEC_DOCKER_IMAGE 对应 terminal_exec_docker_image。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 = "cn"

全部可用配置请参考带注释的配置模板。

环境变量

连接

变量必填默认值说明
WORKER_CONSOLE_GRPC_TARGET否127.0.0.1:50051控制节点 gRPC 地址
WORKER_CONSOLE_INSECURE否false设为 true 允许不安全的连接(非 TLS)
WORKER_ID是Dashboard 中的 Worker ID
WORKER_SECRET是创建 worker 时的一次性密钥

身份

变量必填默认值说明
WORKER_NODE_NAME否可读的节点名称
WORKER_VERSION否构建版本上报给控制节点的版本号
WORKER_LABELS否CSV 格式标签,如 region=us,owner=team-a

Docker 镜像

变量必填默认值说明
WORKER_PYTHON_EXEC_DOCKER_IMAGE否ghcr.io/astral-sh/uv:python3.12-bookworm-slimPython 执行镜像
WORKER_TERMINAL_EXEC_DOCKER_IMAGE否coolfan1024/onlyboxes-runtime:default终端执行镜像

terminalExec 和 terminalResource 都依赖 terminal 执行镜像。如果该镜像不包含 python3,文件探针会在校验、读取或导出元数据之前失败。

默认终端镜像是通用执行镜像,包含 Python 3、Node.js 24、npm、Corepack、常用 shell/文件工具、轻量文档处理库,以及基于 Lightpanda 的 agent-browser。LobeHub 专用 sandbox 工具链请使用 coolfan1024/onlyboxes-runtime:lobehub。

Docker 网络

变量必填默认值说明
WORKER_DOCKER_NETWORK否terminalExec 与 pythonExec 容器使用的隔离 bridge

配置后,Worker 会在连接 Console 前检查该网络:

  • 网络不存在时,使用 bridge driver 创建网络,并设置 com.docker.network.bridge.enable_icc=false;创建完成后再次检查。
  • 网络已存在时,检查 driver 必须为 bridge,且 com.docker.network.bridge.enable_icc 必须明确为 false。
  • Docker inspect/create 执行失败、创建后仍找不到网络、driver 不匹配或 ICC 未关闭时,Worker 会直接启动失败,不会注册到 Console,也不会回退到 Docker 默认网络。

校验通过后,terminal 容器的创建、IP 读取、Session 恢复以及 pythonExec 容器创建都会使用该网络。需要指定 subnet 或 gateway 时,应先由管理员创建网络:

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-custom

未配置时保持原有行为:关闭公开预览时,terminalExec 与 pythonExec 都使用 Docker 默认网络;开启公开预览时,仅 terminalExec 使用自动管理的 onlyboxes-sandbox,pythonExec 仍使用 Docker 默认网络。修改网络配置前应结束该 Worker 上的现存 terminal sessions,否则旧容器无法从新网络恢复。

执行资源

变量必填默认值说明
WORKER_PYTHON_EXEC_MEMORY_MIB否256pythonExec 容器的内存限制,单位 MiB
WORKER_PYTHON_EXEC_CPUS否1.0pythonExec 容器的 CPU 限制
WORKER_PYTHON_EXEC_MAX_PROCESSES否128pythonExec 容器的最大进程 / task 数
WORKER_TERMINAL_EXEC_MEMORY_MIB否256terminalExec 容器的内存限制,单位 MiB
WORKER_TERMINAL_EXEC_CPUS否1.0terminalExec 容器的 CPU 限制
WORKER_TERMINAL_EXEC_MAX_PROCESSES否128terminalExec 容器的最大进程 / task 数

并发上限

变量必填默认值说明
WORKER_ECHO_MAX_INFLIGHT否4echo 最大并发数
WORKER_PYTHON_EXEC_MAX_INFLIGHT否4pythonExec 最大并发数
WORKER_TERMINAL_EXEC_MAX_INFLIGHT否4terminalExec 最大并发数
WORKER_TERMINAL_RESOURCE_MAX_INFLIGHT否4terminalResource 最大并发数
WORKER_TERMINAL_SESSION_MAX_INFLIGHT否1单个 terminal session 的最大并发数;terminalExec 与 terminalResource 共享
WORKER_TERMINAL_MAX_ACTIVE_SESSIONS否0(无限制)当前 worker 进程管理的 terminal session 数量上限

WORKER_TERMINAL_EXEC_MAX_INFLIGHT 和 WORKER_TERMINAL_RESOURCE_MAX_INFLIGHT 分别限制整个 worker 上对应能力的并发数,二者相互独立,没有额外的 worker 全局合计上限。WORKER_TERMINAL_SESSION_MAX_INFLIGHT 则限制单个 session_id,并将 terminalExec 与 terminalResource 合并计数。请求必须同时满足对应能力上限和 session 上限。

WORKER_TERMINAL_MAX_ACTIVE_SESSIONS 是独立的 session 数量上限。0 表示不限制;正数会统计创建中、可用、等待执行中命令结束以及 Docker cleanup 进行中的 session。容量已满时已有 session 仍可使用,新建 session 返回 429 session_capacity_exceeded。负数或非法值回退为 0。

例如将 terminalExec 和 terminalResource 上限都设为 10、单 session 上限设为 2 时,整个 worker 最多可同时处理 10 个 terminalExec 和 10 个 terminalResource,但任一 session 内两类操作合计不能超过 2。超出单 session 上限返回 409 session_busy,对应能力的 worker 级并发额度耗尽返回 429 no_capacity,新建 session 时 session 数量上限耗尽返回 429 session_capacity_exceeded。

终端租约

变量必填默认值说明
WORKER_TERMINAL_LEASE_MIN_SEC否60最短租约时长(秒)
WORKER_TERMINAL_LEASE_MAX_SEC否1800最长租约时长(秒)
WORKER_TERMINAL_LEASE_DEFAULT_SEC否60默认租约时长(秒)
WORKER_TERMINAL_OUTPUT_LIMIT_BYTES否1048576每个流的输出上限(字节)
WORKER_TERMINAL_EXPORT_MAX_BYTES否0(无限制)export action 最大文件大小(字节),0 为无限制

Worker 会声明仅供 Console 内部使用的 terminalLeaseRenew 能力。它接收 {"session_id":"required","lease_ttl_sec":300},以单调方式延长已有租约、重置 session 租约计时器,并在不执行命令的情况下返回确认后的绝对到期时间。该能力拥有独立的 max_inflight,其声明值取自 WORKER_TERMINAL_EXEC_MAX_INFLIGHT 配置。

心跳

变量必填默认值说明
WORKER_HEARTBEAT_INTERVAL_SEC否5心跳间隔(秒)
WORKER_HEARTBEAT_JITTER_PCT否20抖动百分比(0–100)
WORKER_CALL_TIMEOUT_SEC否ceil(2.5 * interval)gRPC 调用超时(秒)

日志

变量必填默认值说明
WORKER_LOG_LEVEL否infodebug / info / warn / error
WORKER_LOG_FORMAT否jsonjson / text
WORKER_LOG_ADD_SOURCE否false是否在日志中包含源文件和行号

相关文档