SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor

OpenBot AI 协作者自托管:VPS 配置与内存成本

了解如何在 VPS 上自托管 OpenBot,让每个 AI 协作者使用独立容器、Chromium 浏览器和工作区,并掌握网关决策流程与单个 Bot 的实测内存成本。

自托管 OpenBot AI 协作者后的运行方式

您可以在自己控制的硬件上运行一个网关服务器,并为每个机器人运行一个容器,从而自托管 OpenBot AI 协作者。每个机器人容器都包含独立的 Chromium 浏览器和独立的工作区卷,并使用可在会话之间持久保存的浏览器配置文件。机器人对计算机、文件、MCP(模型上下文协议)服务器或 UI 组件执行的每个操作,都会先经过该网关。网关会在操作执行前根据策略进行检查,并在执行后记录操作。

CopilotKit 根据 MIT 许可证发布 OpenBot,项目地址为 github.com/CopilotKit/openbot。第一个带标签的版本 v0.0.1 于 17 August 2026 发布。项目将自身描述为 alpha 版本,仍在积极开发中。应将其视为设计严谨但仍存在早期版本局限性的项目。

该架构中最有价值的部分,也是成本最高的部分。每个代理都需要一个浏览器,这是许多人规划时最容易忽略的内存成本。因此,本教程会先进行容量规划,再执行安装。

网关如何决定每项操作

端口 3001 上的 API 服务器是访问 bot 计算机的唯一通道。在执行浏览器操作前,网关会根据页面快照解析目标,针对上下文评估 CEL(通用表达式语言)策略规则,写入包含决策结果的审计记录,然后才调用容器。如果执行随后失败,网关会再写入第二条记录。文档明确说明了这一边界:计算机不负责决定策略,服务器网关才是操作边界。

策略默认拒绝,并且先评估拒绝规则,再评估允许规则。失败方向比规则语法更重要。缺少策略不会允许任何操作;规则损坏时,无论是拒绝规则还是允许规则,结果都会趋向阻止操作。因此,策略中的错误会导致 bot 停滞,而不会导致 bot 脱离控制并访问您的账户。

审计记录存储在 PostgreSQL 中,因此重启后仍然保留。控制权交接记录为 computer.help_requestedcomputer.control_takencomputer.control_released。通过这些记录,您可以看到 bot 请求人工接管,也可以看到人工将控制权交还。密钥只记录字符数,从不记录其值。文件操作记录路径和大小,从不记录文件内容。如果您希望在没有浏览器的情况下实现相同的控制边界,请参阅通过审批限制 AI agent 操作,其中介绍了这一更具体的场景。

单个 Bot 的内存和磁盘开销

该项目公布了 arm64 上单个 Bot 的实测数据。这是 OpenBot 发布的唯一规格数据,而且只描述一种架构上的单个 Bot。因此,应将其作为起始参考,而不是容量规划依据。

ChartOpenBot published resource figures, one Bot on arm64 (August 2026)
The data behind this chart
[
  {
    "label": "Measured, one Bot",
    "memory_gb": 0.55,
    "disk_gb": 5.3,
    "vcpu": 0.06
  },
  {
    "label": "Documented minimum",
    "memory_gb": 2,
    "disk_gb": 8,
    "vcpu": 1
  },
  {
    "label": "Documented recommended",
    "memory_gb": 4,
    "disk_gb": 10,
    "vcpu": 2
  }
]

单个 Bot 的峰值内存实测为 0.55 GB,文档规定的最低值为 2 GB,建议值为 4 GB。实测值与最低值之间的差额用于应对 Chromium 在负载下增长的内存需求,因为浏览器的内存使用量取决于当前打开的页面,而不是空闲进程的内存占用。空闲 CPU 使用量几乎为零,在实测范围的最高值为 0.06 个核心。因此,主要需要规划的不是 CPU,而是磁盘。镜像本身占用 5.3 GB,建议卷大小为 10 GB。镜像之所以较大,是因为除 Chromium 外,还包含 Playwright 的 Firefox 和 WebKit 二进制文件。

这些数据无法说明同时运行多个 Bot 的开销,项目也没有发布相关数据。请自行测量。启动一个 Bot,为其分配一个打开页面的实际任务,并在运行期间监控容器。

docker stats --no-stream
free -m

将该 Bot 容器的 MEM USAGE 列作为单个 Bot 的开销,在此基础上加上 gateway 和 PostgreSQL 的开销,然后将单个 Bot 的开销乘以预计同时存在的 Bot 数量。空闲 Bot 仍会保留浏览器进程,因此乘数适用于所有已存在的 Bot,而不仅是正在处理任务的 Bot。计算方式与为 coding agent VPS 规划 RAM 和 CPU中的方法相同,其中浏览器部分详见在 VPS 上为 agents 运行无头浏览器

有一个 Chromium 细节会影响小型方案。OpenBot 使用 --disable-dev-shm-usage 启动 Chromium,因此浏览器会写入 /tmp,而不是 /dev/shm。这样可以避免在 /dev/shm 较小的主机上发生崩溃,但会将压力转移到根文件系统。这也是建议磁盘空间大于镜像大小的另一个原因。

如何在 VPS 上自行托管 OpenBot?

您需要 Docker、Bun 1.3 或更高版本、一个 CopilotKit Intelligence 项目,以及模型 API 密钥。开发文档还要求服务器上存在 lsofpython3curl。请克隆带标签的发行版,而不是 main,因为 alpha 项目中的 main 可能在没有警告的情况下发生变化。

git clone --branch v0.0.1 https://github.com/CopilotKit/openbot.git
cd openbot
cp .env.example .env

配置 Intelligence 项目。以下 3 条命令会将运行时密钥和许可证令牌写入环境文件。

npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --write

生成用于加密已存储凭据的密钥,并将输出写入 .env,格式为 KEY_ENCRYPTION_KEY。在同一文件中添加您的 OPENAI_API_KEY,或者将 BOT_PROVIDER 设置为 anthropicgoogle,并配置匹配的密钥。

openssl rand -base64 32

然后安装并启动服务。

bun install
bash scripts/start.sh

scripts/start.sh 会启动 Docker 服务,执行数据库迁移,启动服务器和应用,并检查它们的运行状况。完成后,应用会在端口 3010 上响应,API 会在端口 3001 上响应。该脚本会报告端口冲突,并让已在运行且匹配的服务保持不变,因此重复运行是安全的。

在对外开放任何服务前,先从服务器本机进行检查。

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3010
ss -ltnp | grep -E ':(3010|3001|4100|4500|5432)'

第一条命令返回 200,表示应用正在提供服务。第二条命令会显示这些端口绑定的地址;在 VPS 上,绑定地址才是需要关注的结果。显示 127.0.0.1:3001 的行表示服务仅对本机可用。显示 0.0.0.0:3001 的行表示任何能够路由到该服务器的主机都可以访问服务。

单个容器镜像

部署文档还提供了一个包含应用、API 和 Chromium 的单个镜像,服务监听 3001 端口。

docker build -t openbot .
docker run -p 127.0.0.1:3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql/data openbot

EMBEDDED_POSTGRES=on 在容器内运行 PostgreSQL,并在启动时执行迁移。命名卷可在重新部署后保留审计历史;没有该卷时,每次重新构建都会丢弃这些历史记录。如果改为让 DATABASE_URL 连接托管数据库,则必须在该数据库上启用 vector 扩展。RDS、Cloud SQL 和 Azure Database 等托管服务支持该扩展,但都不会自动为您启用。因此,针对全新的托管数据库执行迁移会失败,因为其中尚不存在 vector 列类型。

数据库位于外部时,应将迁移作为发布步骤执行。

docker run --rm --env-file .env openbot \
  sh -c "cd /app/server && bun x drizzle-kit migrate --config=drizzle.config.ts"

该镜像有意不发布浏览器端口。它也不包含 supervisor,因为 supervisor 需要 Docker socket,而无服务器平台不提供该接口。没有 supervisor 时,所有 bot 共用一个浏览器,也共用一组登录凭据,因此失去了按 bot 使用容器所带来的隔离性。如果您需要为每个 bot 使用独立登录凭据,请在接受这一取舍的主机上运行 compose stack,并设置 COMPUTER_SUPERVISOR_URLSUPERVISOR_TOKEN。能够与 Docker socket 通信的进程可以启动特权容器,因此实际上拥有该主机上的 root 权限。正因如此,最好将 OpenBot 放在独立机器上,这与为编码代理提供一次性 VM的做法一致。

为何 OPENBOT_SINGLE_USER 是笔记本设置

.env.example随附OPENBOT_SINGLE_USER=true。启用该设置后,所有请求都会被视为来自同一个管理员,并完全跳过登录。在笔记本上,这很方便,因为只有您能够访问该端口。在 VPS 上,这意味着第一个访问 3010 端口的人就会成为系统管理员,而该系统存储加密凭据,并驱动一个已登录您各个账户的浏览器。

有两种安全可靠的运行方式。保留OPENBOT_SINGLE_USER=true,将每个端口绑定到127.0.0.1,然后仅通过 SSH 隧道或专用网络接口访问应用。

ssh -N -L 3010:127.0.0.1:3010 -L 3001:127.0.0.1:3001 you@your-vps

此时,您可以在自己的浏览器中通过http://localhost:3010访问应用。浏览器会将其视为安全上下文,因此登录 Cookie 和实时画面所需的浏览器功能都能正常工作。另一种方式是关闭单用户模式,并配置真正的身份提供商。支持 Google、Microsoft Entra、Okta、SAML 和 OIDC。无论使用哪种提供商,都还需要长度至少为 32 个字符的BETTER_AUTH_SECRET、将BETTER_AUTH_URL设置为 OAuth 回调使用的公网 API 基础 URL、INITIAL_ADMIN_EMAILS以及TRUSTED_ORIGINS。提供商凭据必须完整,因为配置不完整的提供商会阻止服务启动,而不会回退到开放访问模式。

如果应用可通过公网域名访问,请在其前面配置 TLS(传输层安全协议)。在 localhost 以外的地址上通过纯http://提供页面,不属于安全上下文。因此,标记为Secure的 Cookie 不会被存储,登录会失败,看起来就像是 OpenBot 的程序错误。

封锁较低层端口

OpenBot 的安全说明指出,较低层服务端点通过令牌保护,应保持私有,不应利用这些端点绕过网关。令牌是第二层防护。第一层防护是端口根本无法访问。

agent-computer 监听 4100,并要求 COMPUTER_TOKEN。机器人端点监听 4200 和 4201。supervisor 在主机上监听 4500,在其容器内监听 4300。PostgreSQL 监听 5432。这些端口都不应绑定到公网接口;在单用户部署中,app 和 API 也不应绑定到公网接口。

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

这里有一个容易忽略的问题:有些人会以为防火墙已经足够。使用 -p 3001:3001 发布容器端口时,Docker 会安装 DNAT 规则,使流量在 FORWARD 路径中处理,不会经过 ufw 默认拒绝规则所控制的 INPUT 链。即使 ufw status 仍显示 Status: active,该端口依然处于开放状态。应直接在端口映射中将已发布端口绑定到 loopback,例如 -p 127.0.0.1:3001:3001,也可以在 compose 文件中设置主机地址。使用 ss -ltnp 验证,不要使用 ufw status

OpenBot 不是离线部署栈

在规划部署前先明确这一点。OpenBot 依赖 CopilotKit Intelligence 项目,该项目在您的服务器之外保存持久化线程和对话记忆。服务器启动时会验证 INTELLIGENCE_API_URLINTELLIGENCE_GATEWAY_WS_URLINTELLIGENCE_API_KEYCOPILOTKIT_LICENSE_TOKEN,这4项必须同时存在,否则启动会失败。截至 August 2026,已有免费计划可用。Intelligence 本身也支持自行托管,因此可以实现完全本地化部署,但所需工作量会超过快速入门文档展示的内容。

模型是第二个外部依赖。该软件包不附带模型。BOT_PROVIDER 接受 openaianthropicgoogle,而 OPENAI_BASE_URL 可将 OpenAI 路径指向任意兼容端点。如果您希望令牌始终保留在自己的硬件上,可使用 在 VPS 上运行 Ollama 以自行托管 LLM。浏览器控制对模型的要求较高,因此在决定使用本地模型前,应先让它完成真实任务并进行测试。

暂时运行 1 个副本

网关会将页面快照缓存在服务器进程的内存中。运行 2 个副本时,一个进程创建的快照对另一个进程不可见,因此操作会间歇性失败,并出现看似随机的元素未找到错误。部署文档明确要求运行单个副本,并将平台的最大实例数固定为 1。快照缓存迁移到数据库后,才能取消此限制。在此之前,应通过升级服务器配置来扩展 OpenBot,而不是增加服务器数量。各个 bot 之间仍通过独立容器实现隔离,原理与 自托管代理沙箱 相同,可避免一个代理的错误影响其他代理。

故障模式及其表现

填写 .env 后,启动立即退出。 服务器会先验证配置,然后才开始提供服务。Intelligence 配置块不完整、缺少 KEY_ENCRYPTION_KEY,或 OAuth 提供商配置了客户端 ID 但未配置密钥,都会导致启动失败,而不是静默降级。读取第一条错误,修正对应字段,然后再次启动。

托管数据库上的迁移失败。 默认未启用 vector 扩展,因此迁移操作遇到了 PostgreSQL 不识别的列类型。以 superuser 身份连接,运行 CREATE EXTENSION vector;,然后重新执行迁移步骤。

应用可以加载,但登录状态始终无法保留。 您通过公网地址使用普通 http:// 提供服务。该地址不属于安全上下文,因此浏览器会丢弃 Secure cookie。请在前面配置 TLS,或使用 SSH 隧道,让浏览器看到 localhost

原本应相互隔离的 bot 共用了登录状态。 supervisor 未运行,因此没有为每个 bot 分配独立计算机,所有 bot 都使用共享浏览器。确认已设置 COMPUTER_SUPERVISOR_URL,并确认 supervisor 可以访问 Docker socket。

bot 停止并请求帮助。 这表示系统按设计运行。审计跟踪会记录 computer.help_requested,您可在实时屏幕上接管操作,交接过程也会在双方记录。

FAQ

将 OPENBOT_SINGLE_USER 留在 VPS 部署中是否安全?

仅当网关无法从互联网访问时才安全。OPENBOT_SINGLE_USER=true 会将每个请求都视为同一个管理员发出,且无需登录。因此,任何能够打开该端口的人都可以控制整个部署、其中存储的凭据以及已登录的浏览器。只有在所有端口都绑定到 127.0.0.1,并且通过 SSH 隧道或私有网络接口访问应用时,这种配置才可接受。在公网上,应将其关闭,并配置 Google、Microsoft Entra、Okta 或 OIDC,同时设置 BETTER_AUTH_SECRETBETTER_AUTH_URLINITIAL_ADMIN_EMAILSTRUSTED_ORIGINS

一个 OpenBot bot 需要多少 RAM?

项目公布的单个 arm64 Bot 数据显示,其峰值内存为 0.55 GB,文档记录的最低值为 2 GB,建议值为 4 GB。项目没有公布同时运行多个 bot 时的数值,因为每个 bot 都会独占一个 Chromium。让一个 bot 执行实际任务,在 docker stats 中读取该容器的内存使用量,加上网关和数据库的开销,然后乘以预计同时运行的 bot 数量。

自托管 OpenBot 是否需要 CopilotKit 账户?

需要。OpenBot 依赖 CopilotKit Intelligence 项目来持久化线程和记忆。如果未设置 Intelligence API URL、网关 WebSocket URL、API key 和 license token,服务器将拒绝启动。截至 August 2026,CopilotKit 提供免费计划;Intelligence 也可以自托管,因此经过额外配置后可以移除托管依赖。你还必须提供自己的模型 API key,因为 OpenBot 不附带任何模型。

为什么每个 bot 都使用独立的浏览器,而不是共享一个?

因为浏览器配置文件代表一个身份。共享浏览器意味着共享 cookies 和会话,因此一个 bot 登录某个账户后,所有 bot 都会登录该账户。每个 bot 使用独立容器后,每个协作者都有自己的配置文件和登录信息。代价是内存开销,因为每个 bot 独占一个 Chromium,这是资源估算中最大的单项开销。

防火墙应开放哪些 OpenBot 端口?

底层端口都不应开放。agent-computer 使用的 4100 端口、bot 端点使用的 4200 和 4201 端口、supervisor 使用的 4500 端口,以及 PostgreSQL 使用的 5432 端口,都应保持私有。项目通过令牌保护这些端口,并要求你始终避免让它们可访问。只发布用户实际需要访问的端口。还要注意,使用 -p 3001:3001 发布的容器端口不受 ufw 的 default-deny 规则限制,因为 Docker 的 DNAT 规则会将这些流量放入 FORWARD 路径,而不是 INPUT