官方当前的 VM 自托管示例会把静态前端、Agent Server 和自动化后端放在同一台主机上,再由 127.0.0.1:8000 的入口代理统一转发。症状:本地任务因电脑休眠、合盖或 SSH 断开而中断。最快解法:先把 OpenHands Agent Canvas 远程 VM 部署到独立、可重建的主机,再用私网验收,最后补齐 API Key、TLS、保活和沙盒。(参考 OpenHands 官方自托管架构)
经常让笔记本休眠后任务消失的个人开发者,适合直接从本文开始。
需要给团队提供共享 Agent 后端的平台与 DevOps 工程师,也可以按时间线逐阶段上线。
如果你的目标是 Xcode、模拟器或签名构建,则应读到最后,再判断是否增加远程 Mac。
最后更新于 2026 年 8 月 14 日,启动方式、公共访问路径、鉴权机制、镜像标签和后端关系核实自 OpenHands 官方自托管指南、Agent Canvas 官方仓库、官方版本发布页 和 Agent Server 文档索引。
独立 VM 与本地开发机的边界
把 Agent Canvas 直接装在个人电脑上,最大的问题不是“能不能启动”,而是执行边界不清楚:Agent Server 可能读写主机文件、执行 Shell 命令并访问网络;一旦工作目录、环境变量或凭据没有隔离,开发机就会同时变成控制台、构建机和凭据仓库。能访问 Agent Server 的人,可能获得与该 Agent 相同的文件系统和网络能力,因此本地开发机不适合作为团队共享的长期后端。
你需要先区分三种边界:
| 部署边界 | 适合任务 | 主要风险 | 建议 |
|---|---|---|---|
| 控制服务 | 前端、后端路由、任务记录 | 服务可用但执行节点不稳定 | 可与 Agent Server 同机起步 |
| 代码构建 | 编译、测试、依赖安装 | 消耗 CPU、磁盘和网络,可能污染主机 | 使用独立工作目录 |
| 外部沙盒 | Docker 或专用执行节点 | 文件挂载、凭据和网络权限复杂 | 高风险任务优先隔离 |
官方架构将 Agent Canvas 定义为前端控制层,真正执行任务的是 Agent Server;一个 Agent Server 运行在单一主机与端口上,Agent Canvas 可以连接多个后端并切换。自动化后端则负责计划任务或事件触发,不能把它误认为沙盒本身。
因此,第一台主机最好是独立、可重建的 Linux VM。普通代码分析、Web 服务测试和多数后端构建留在 Linux;只有 Xcode、模拟器、签名或 macOS 原生依赖出现时,再配置远程 Mac 节点。
私网最小启动路径
1.准备运行时
官方 README 当前要求 Node.js 22.12.x 或更高版本,并使用 uv 运行 Agent Server。Ubuntu 主机可以先安装 curl、git 和 uv,Node.js 则通过你团队现有的版本管理方式安装;不要在没有锁定运行时版本的情况下,把生产服务交给系统自带的旧 Node。(参考 OpenHands 官方 README 的运行环境说明)
sudo apt-get update
sudo apt-get install -y curl git openssl
curl -LsSf https://astral.sh/uv/install.sh | sh
确认运行时:
node --version
uv --version
版本命令只用于验收,不要把未经核实的“最低 CPU、内存或磁盘”写进部署标准。官方当前自托管资料没有给出统一资源下限,实际容量应根据并发 Agent、仓库规模和构建工具链测试。
2.生成独立 API Key
不要把 Key 写入 Git 仓库、网页源码、.env 示例文件或会被团队共享的截图。官方示例使用 openssl rand -base64 32 生成密钥,并通过 LOCAL_BACKEND_API_KEY 传给 Agent Canvas。(参考 官方 API Key 配置示例)
export LOCAL_BACKEND_API_KEY="$(openssl rand -base64 32)"
printf '%s\n' "$LOCAL_BACKEND_API_KEY"
把输出保存到受限权限的密码管理工具或部署密钥系统中。若你使用 systemd,建议把环境变量放进权限为 600 的独立 EnvironmentFile,而不是直接把密钥暴露在公开的服务仓库里。
3.先启动私网模式
npx @openhands/agent-canvas --public
官方自托管路径会启动静态前端、Agent Server 和自动化后端,并由本机入口代理统一转发。当前文档示例中,入口代理监听 127.0.0.1:8000,Agent Server 与自动化后端使用内部服务端口;这些端口属于当前架构示例,不应当被当作永远不变的公共 API。
首轮不要直接放行公网,使用 SSH 隧道:
ssh -N -L 8000:127.0.0.1:8000 user@your-vm
然后在本地浏览器访问:
http://127.0.0.1:8000
此时应完成四项验证:
- 页面可以打开,并出现 API Key 输入界面;
- 后端状态显示在线;
- 指定仓库能够读取,工作目录没有指向错误主机;
- 创建一个短任务后,实时事件能够持续返回,而不是只在任务结束时一次性刷新。
安全边界与 Docker 沙盒
直接运行的优点是路径少、故障点少;缺点是 Agent Server 与主机共享文件系统、环境变量和网络。Agent 会直接获得安装主机上的文件访问能力,因此这种模式更适合个人测试或受控私网,不适合在没有额外隔离的情况下处理不可信仓库。
Docker 沙盒可以把执行环境与控制主机分开,但它不是自动安全。你仍然需要审查项目目录挂载、Docker Socket、凭据注入、出站网络和容器用户权限。官方 Docker 示例要求准备 PROJECTS_PATH,容器可以访问该路径下的项目,因此不要把整个家目录或含有 SSH 私钥的目录挂载进去。(参考 OpenHands 官方 Docker 运行说明)
| 方式 | 文件访问范围 | 隔离强度 | 适合场景 | 上线评分 |
|---|---|---|---|---|
| 主机直跑 | 由主机权限决定 | 较低 | 个人测试、受控私网 | ★★★☆☆ |
| Docker 沙盒 | 由挂载路径决定 | 中等 | 团队共享、第三方仓库 | ★★★★☆ |
| 独立执行节点 | 节点级隔离 | 较高 | 高风险任务、持续自动化 | ★★★★★ |
第一次安全验收不要只测“错误 Key 会不会失败”,还要测试:
1.用错误 API Key 请求接口;
2.让 Agent 尝试读取工作目录以外的文件;
3.让 Agent 执行删除、改权限或访问凭据目录的命令;
4.检查日志中是否出现 API Key;
5.确认项目目录以外的环境变量没有被无意注入。
如果越权读取或未授权请求仍然成功,先回退到私网,不要继续配置域名和公网入口。
TLS、长连接与进程保活
公网访问至少要有三层:云防火墙、反向代理和应用层 API Key。官方示例建议让 nginx 接收 HTTPS,再把请求转发到本机入口;公网不需要直接暴露 Agent Server 的内部端口。防火墙通常只放行管理所需的 SSH,以及反向代理使用的 HTTP/HTTPS 入口,SSH 应进一步限制来源 IP。
| 访问层 | 作用 | 验收证据 |
|---|---|---|
| 云防火墙 | 阻止内部端口被直接扫描 | 外部无法访问内部服务端口 |
| nginx | 统一接收域名和 HTTPS | HTTP 自动跳转 HTTPS |
| API Key | 阻止未授权 Agent 请求 | 错误 Key 返回拒绝 |
| WebSocket/SSE 转发 | 保持实时任务事件 | 长任务期间事件持续刷新 |
nginx 的关键不是普通页面代理,而是长连接参数。官方配置包含 HTTP/1.1、Upgrade、Connection 以及较长的读写超时,用于支持实时 Agent 事件。缺少这些配置时,页面可能能打开,但任务执行过程中会出现事件中断或状态长时间不更新。(参考 官方反向代理配置说明)
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
测试配置:
sudo nginx -t
sudo systemctl reload nginx
curl -I https://canvas.example.com/
curl -I http://canvas.example.com/
长期运行不要依赖当前 SSH 会话。tmux 适合快速验证:
tmux new-session -d -s canvas \
'npx @openhands/agent-canvas --public'
正式部署使用 systemd:
[Unit]
Description=Agent Canvas
After=network.target
[Service]
EnvironmentFile=/etc/openhands/agent-canvas.env
ExecStart=/usr/bin/npx @openhands/agent-canvas --public
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now agent-canvas
sudo systemctl status agent-canvas
如果 npx 的实际路径不同,以 command -v npx 的结果替换 ExecStart,不要照抄路径。验收必须包含主动退出 SSH、杀掉进程、重启主机和检查日志轮转四个动作。
后端切换与工作目录
本地前端可以把远程主机注册为额外后端,让本地、远程 VM 与专用构建节点分别承担不同任务。切换后端并不等于同步文件,也不会自动把本地未提交代码上传到远程主机。
| 后端 | 推荐职责 | 代码进入方式 | 不适合 |
|---|---|---|---|
| 本地机器 | 临时调试、交互式修改 | 本地文件 | 长时间无人值守 |
| Linux VM | 分析、测试、后端构建 | Git、受控传输 | Xcode 与 macOS 专属工具 |
| 远程 Mac | Xcode、签名、模拟器 | Git 或专用同步流程 | 普通 Linux 服务测试 |
切换前固定检查三件事:仓库远程地址是否正确、工作目录是否属于目标节点、LLM 与 Agent 配置是否落在预期后端。建议用 Git 作为主要同步边界:先提交或创建临时分支,再让远程 Agent 拉取;不要把“前端已经显示远程”误认为“本地未提交文件已经存在于远程”。
FAQ:云服务器、保活与远程 Mac
OpenHands Agent Canvas 的云端安装
云服务器是官方支持的部署形态,但“可以安装”不代表“可以直接公网开放”。最小路径应是独立 VM、私网访问、API Key 和受限工作目录;只有完成任务事件、权限和重启测试后,才进入域名与 TLS 阶段。
Agent Server 的端口策略
不要依据旧教程猜测默认端口。当前官方自托管图示展示了入口代理、Agent Server 与自动化后端的关系,但内部端口可能随版本变化;你的防火墙规则应尽量只暴露 SSH 和 HTTPS,内部端口保持回环或私网可达。
远程 Mac 的使用条件
远程 Mac 不是为了替代所有 VM,而是为 macOS 工具链服务。你可以先在 Linux VM 上完成仓库分析、依赖检查和大多数测试,等任务明确出现 Xcode、模拟器、签名或原生框架要求后,再把该任务路由到远程 Mac。
上线前可勾选验收清单
- [ ] VM 与个人开发机分离,能够通过镜像或脚本重建;
- [ ] Node.js 与
uv版本通过命令确认,并记录在部署文档; - [ ] API Key 使用独立随机值,未写入仓库、前端文件和普通日志;
- [ ] 首次访问只通过 SSH 隧道、VPN 或受限私网完成;
- [ ] 工作目录只包含允许 Agent 处理的项目;
- [ ] 已测试错误 Key、越权读取和危险命令;
- [ ] nginx 已配置 HTTPS、长连接转发和合理超时;
- [ ] SSH 断开后任务仍继续,进程异常后能够自动恢复;
- [ ] 主机重启后 Agent Canvas、反向代理和证书续期状态正常;
- [ ] 本地、Linux VM 与远程 Mac 的仓库同步流程已经写清楚;
- [ ] 使用实际仓库完成一次任务、一次重启恢复和一次构建闭环。
Linux VM 与远程 Mac 的最终选择
如果你的任务主要是代码分析、依赖升级、Web 服务测试、后端构建或普通自动化,Linux VM 通常已经足够。它的缺点是不能原生提供 Xcode、Apple 模拟器和 macOS 签名链;而本地电脑虽然有这些工具,却容易受休眠、网络切换和个人权限变化影响。
当仓库确实依赖 macOS 工具链时,增加远程 Mac 比在 Linux 上绕过系统限制更稳妥。你可以先参考 Mac 远程连接方式,再根据实际是否需要持续运行、图形界面和专用构建节点,了解 Mac mini 租赁方案。如果只是首次部署或排查连接问题,也可以先查看 SSHMac 帮助中心。
真正适合长期上线的方案,不是把所有任务都塞进一台机器,而是让 Linux VM 负责通用 Agent 工作,让远程 Mac 只承接 Xcode、模拟器和签名构建。完成最小 VM 部署后,按你的仓库工具链逐项核对:没有 macOS 专属依赖,就继续使用 Linux;只要出现不可替代的 macOS 构建步骤,再增加可持续运行的远程 Mac 节点。