Skip to content

干净服务器从零部署 ​

这一页是写给谁的

你刚拿到一台全新 Ubuntu / Debian 服务器(云主机、自己电脑装的虚拟机、公司内网机器都算),想从零跑起 anet hub + 一两个节点 + Telegram 接入,端到端跑通。

每一步都带验证命令,文末有常见报错对照表(故障排查表)。

不是给已经装好 anet 的人看的,那个走 上手指南 或 升级指南。 已有 Hub 要搬到另一台机器,请走 迁移 Hub,不要把从零部署当数据恢复。

0. 前置 ​

按安装装好 Node.js ≥ 22.13 和 Bun ≥ 1.2(两个都要装,Hub 由 Bun 运行)。之后要用 systemd、cron 或另一个用户启动 Hub 和节点时,先看安装页里关于 PATH 的说明。

1. 安装 anet CLI ​

bash
npm install -g @sleep2agi/agent-network
anet -v

anet -v 会列出 agent-node、commhub-server 是否已就位(首次使用时自动拉取),以及本机装了哪些可选 runtime CLI。后面任何启动出错,先看这里。

2. 起 Hub(推荐 tmux 挂着) ​

CommHub 是常驻进程,关终端就停。生产场景配 systemd(§8 持久化),快速验证用 tmux:

bash
# 装 tmux(如果没装)
sudo apt install tmux -y    # Ubuntu / Debian

# 起一个名叫 anet-hub 的会话挂 hub
tmux new -s anet-hub
anet hub start --host 0.0.0.0 --port 9200

# 看到下面这段就 OK
# CommHub MCP Server <version>
# REST:   http://0.0.0.0:9200/api
# ✅ Admin account created
# username: admin
# password: anet-<22 位随机十六进制>   ← 只打印这一次,当场存下

按 Ctrl+B 然后 D 把 tmux 会话断开但保活。回来用 tmux a -t anet-hub 再 attach。

验证 hub 在跑(另一个终端):

bash
curl -s http://127.0.0.1:9200/health | head -5
# 期望返 {"ok":true,"version":"<version>",...} 之类

公网部署立刻改密

首次启动打印的随机密码只显示一次。任何 --host 0.0.0.0 公网部署都要立刻改成自己的强密码:

bash
anet login --username admin --password '<启动时打印的密码>' --hub http://127.0.0.1:9200
anet passwd          # 交互改强密码(≥ 8 位 + 非弱密码字典)

或起 hub 时直接设:anet hub start --host 0.0.0.0 --username <your-admin> --password '<strong-pass>'。

端口被占?换端口或停旧 hub
bash
# 查看谁占了端口
ss -tlnp | grep 9200

# 换端口
anet hub start --port 9201

# 或优雅停掉旧 hub (推荐)
anet hub stop                  # 默认端口 9200, SIGTERM → 3s grace → SIGKILL 兜底
anet hub stop --port 9201      # 非默认端口
anet hub status                # 看当前 PID / 端口 / commhub-server 版本

# 万一以上不可用, 兜底手动停
HUB_PID=$(ss -tlnp | grep ':9200' | sed -E 's/.*pid=([0-9]+).*/\1/' | head -1)
kill "$HUB_PID"
# 或如果你的 hub 跑在 tmux 里, 直接 attach + Ctrl+C
tmux a -t anet-hub             # 然后按 Ctrl+C 停, Ctrl+B D 留 tmux 会话

较旧的版本(如 2.2.12)anet hub --help 不列出 stop / status,但命令本身可用:anet hub status 会返回 hub running / vX.Y.Z / pid N。

3. CLI 登录 ​

第三个终端(保持 hub 那个 tmux 不动):

bash
anet login --hub http://127.0.0.1:9200 --username admin --password '<启动时打印的密码>'

登录后 Token 写到 ~/.anet/config.json,后续 anet node ... 命令自动带凭证。

bash
anet whoami          # 确认身份

4. 建 Agent 节点(按 runtime 选) ​

bash
anet node create my-bot

向导会按这个顺序问你:

text
节点名 → runtime → (仅 claude-agent-sdk 才弹) vendor → model → API Key / 鉴权

runtime 是第一道分叉,决定后面要不要配 vendor、要装什么依赖。 选单列出全部 7 个 runtime,下表是常用的几个;npm 包、主推模型和完整的 wizard 行为对照见 runtimes — Runtime 对比 (canonical):

Runtime复杂度适合wizard 后续额外依赖
claude-code-cli(推荐入门)⭐已经在用 Claude Code,想复用订阅跳过 vendor + model,直接走本机 claude 登录态本机已 claude auth login
claude-agent-sdk⭐⭐程序化用 Anthropic 兼容 API(MiniMax / 书生 / 小米 MiMo 等国产模型走这里)弹 vendor 子菜单 → 选 vendor → 选 model → 填 API KeyAPI Key
codex-sdk⭐⭐⭐写代码 / 跑命令,用 OpenAI Codex跳过 vendor,走 codex 登录态agent-node + codex CLI + codex login
grok-build-acp⭐⭐⭐用 xAI Grok Build 跑任务跳过 vendor,走 grok 登录态 + GROK_CODE_XAI_API_KEYgrok CLI + grok login + GROK_CODE_XAI_API_KEY
opencode-cli (preview)⭐⭐⭐用公版 sst/opencode CLI 当多 vendor 前端(预览;latest 与 preview 的选单里都有)选 vendor preset (anthropic / openai),key 从 env 读opencode CLI + Anthropic/OpenAI env key

runtime 默认项注意

向导默认高亮第一项(当前是 claude-agent-sdk),新手一路按 Enter 会落到这条要配 vendor + API Key 的路径上。建议手动选 claude-code-cli,入门最快。

向导不问 Telegram

建节点向导走完(上表所有步骤)就结束,全程不会问你要 Telegram bot token / 白名单 UID。Telegram 是建完节点后用单独命令 anet channel add telegram 加上去的(第 6 节)。

如果你看到 anet create 开头的提示里有 "optional Telegram channel" 那一行,不要以为向导会顺便配,实际不会。

完成后节点配置写到当前目录下:

text
.anet/nodes/my-bot/config.json

验证:

bash
anet node ls         # 应列出 my-bot

5. (codex-sdk 专属)额外装 agent-node + codex CLI ​

如果上一步选了 codex-sdk 或 claude-agent-sdk runtime,节点跑起来要 @sleep2agi/agent-node 包。它在首次使用时通过 npx 懒加载;如果没拉到,启动会报 agent-node is not installed or cannot report a version. Run: anet upgrade。

兜底手动装一次:

bash
npm i -g @sleep2agi/agent-node

# 验证
agent-node --version    # 应输出版本号

codex-sdk runtime 还要装 codex CLI 并登录:

bash
# 注意是 @openai/codex (CLI 工具), 跟 @openai/codex-sdk (codex-sdk runtime 拉的 SDK 库) 是两个 npm 包
npm i -g @openai/codex
codex login        # 浏览器 OAuth

# 验证
codex --version

claude-agent-sdk runtime 不需要装 codex / claude CLI,只要在节点 config 里填了对应 vendor 的 API Key(或对应 env vars ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN)就行。

6. 配 Telegram channel(可选) ​

如果你想从 Telegram 直接给 agent 发任务:

6.1 拿 bot token + 你的 Telegram User ID ​

  1. Telegram 里搜 @BotFather → /newbot → 一路按提示,最后给你一段 bot-token(形如 1234567:ABCDef...)
  2. 拿你的 Telegram User ID(数字):找 @userinfobot 发任意消息,它会回你的 UID

6.2 给节点加 telegram channel ​

bash
anet channel add telegram my-bot \
  --bot-token <bot-token> \
  --allow <uid>

参数:

  • <bot-token>:BotFather 给的串
  • <uid>:能给这个 bot 发任务的 Telegram User ID(多个用逗号隔开:--allow 11111,22222)

验证落地:

bash
anet channel ls
# 应列出: my-bot (my-bot) telegram     allow: <uid>

想加更多人?

anet channel add telegram <node> --allow <new-uid-list> 会覆盖 allowlist,不是追加。要保留原来的人就把完整列表再传一遍(--allow 11111,22222,33333)。更多已知限制见 guide/channels.md。

7. 启动节点 ​

bash
# 推荐 tmux 挂着(跟 hub 同款,免得关终端停)
tmux new -s anet-my-bot
anet node start my-bot

claude-code-cli 节点首次启动会弹「dev-channels 确认框」

claude-code-cli runtime 首次启动会弹 Claude Code 的 --dangerously-load-development-channels 确认框:

text
❯ 1. I am using this for local development
  2. Exit

按 1 + Enter。脚本化 / detached 启动时没人按会卡住,节点一直显示 offline。

兜底:先用 tmux 前台手动按一次,之后再考虑 systemd 接管。Claude Code 那个确认是会话级的,首次按完后续就不弹了。

看到 SSE connected 即节点上线,回 hub 那边 anet status 应列出 my-bot online。

按 Ctrl+B D 把 tmux 断开保活。

8. 持久化(systemd / tmux) ​

下面给两条可选路径:tmux 临时挂、systemd 单元长期跑。

8.1 tmux 临时挂(开发 / 验证) ​

机器重启会丢,需要手动重起:

  • hub: tmux new -s anet-hub + anet hub start --host 0.0.0.0
  • 每个节点: tmux new -s anet-<alias> + anet node start <alias>
  • 想接 @reboot crontab 也行,但 PATH / nvm 这些非交互 shell 问题要先解决(见 第 0 节)

复核节点真起来,别只看 stdout ✅

起完每个节点跑一条:tmux has-session -t "=<alias>"; echo $? 应输出 0。= 必须写,裸名字是前缀匹配,会命中别的 session 假报绿。早于 2.3.0-preview.40 的版本在 detached 场景可能打印 ✅ started detached (tmux session live) 并 exit 0,但 tmux 里没有进程。批量起用 anet project up,它的退出码在 ≥ 2.3.0-preview.40 上可信。

8.2 systemd unit(生产 / 开机自启) ​

下面这套 unit 文件未经官方测试,按你的实际 anet 路径(which anet)+ 运行用户改一下就能用。改完跑 systemctl daemon-reload + enable --now。

Hub /etc/systemd/system/anet-hub.service:

ini
[Unit]
Description=Agent Network Hub
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser
# 用 which anet 拿到真实绝对路径替换 ↓
ExecStart=/home/youruser/.nvm/versions/node/v22.13.0/bin/anet hub start --host 0.0.0.0 --port 9200
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Node(templated,一份 unit 跑 N 个节点)/etc/systemd/system/anet-node@.service:

ini
[Unit]
Description=Agent Network Node %i
After=anet-hub.service
Requires=anet-hub.service

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser
ExecStart=/home/youruser/.nvm/versions/node/v22.13.0/bin/anet node start %i
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

启用:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now anet-hub
sudo systemctl enable --now anet-node@my-bot
sudo systemctl status anet-hub anet-node@my-bot

踩坑提醒:

  • ExecStart 必须填 anet 的绝对路径(which anet),systemd 不会读 nvm ~/.bashrc
  • User= 用你日常装 anet 的那个用户,不要用 root
  • claude-code-cli runtime 首次跑会弹 dev-channels 确认框(见 §7 启动节点),systemd 接管前先 tmux 前台跑一次按掉
  • 想要官方 unit / 改进上面这份?欢迎 PR 或来 GitHub Discussions 提

在容器里跑 ​

仓库目前没有受维护的生产 compose 套件,仓库里的 Dockerfile 和 compose 文件用于测试或特定集成。在容器里跑时,把容器当成「带 Node.js 和 Bun 的 Ubuntu」,上面每一步的命令都一样。可以参考 tests/Dockerfile(Node.js + Bun + anet 的最小集)起步,生产上自行加多阶段构建、镜像 hash 固定和非 root 用户。

  • 启动顺序不变:Hub → Dashboard → anet login → anet node create → anet project up,容器化只是把它们分到不同 service。
  • 首次启动慢:第一次 anet hub start 会从 npm 拉固定版本的 commhub-server,缓存在 $HOME/.bun/install/cache,预热这个目录可以显著提速。
  • 容器间互通:Dashboard 通过 REST + SSE 调 Hub 的 :9200,两者要在同一个 docker network,或把 Hub 端口发布到宿主机。容器里的 localhost 指容器自己。
  • 持久化:节点状态在工作目录下的 .anet/nodes/<alias>/,Hub 数据在 ~/.commhub/,都要挂成 volume。
  • 不要让节点进程当 PID 1:用 tini 这类 init 包一层,否则 SIGTERM 会跳过节点的离线通知。

故障排查表 ​

按部署步骤的顺序排列,报错 → 原因 → 解法:

#现象原因解法
1anet hub start → spawn bunx ENOENT + node stack crash机器没装 Bun,commhub-server 是 Bun-shebang TSnpm i -g bun 或 curl -fsSL https://bun.sh/install | bash;之后 bun --version 应有输出
2anet node create 选完 runtime → FATAL: TypeError: fetch failed建节点要连本地 hub,但 hub 没起(多半因为第 1 条)另开终端先 anet hub start,再回这条重试
3一路 Enter 落到要填 vendor + API Key 的复杂路径runtime 菜单默认高亮 claude-agent-sdk,不是最易上手的 claude-code-cli建节点时手动选 claude-code-cli(已 claude auth login 直接复用订阅)。中断 vendor 选择如果留下半成品节点,用 anet node delete <alias> 清掉重来
4建完节点 Telegram 不工作,但向导开头说"optional Telegram channel"向导不问 Telegram,那行文案有误导Telegram 用 anet channel add telegram <node> --bot-token <tok> --allow <uid> 单独配(见 第 6 节)
5anet node start (codex-sdk / claude-agent-sdk) → agent-node is not installed or cannot report a versionnpx 懒加载没拉到 @sleep2agi/agent-node;≤ 2.3.0-preview.37 的构建(含 2.2.x)有这个问题短路:npm i -g @sleep2agi/agent-node 让二进制就位;长期:anet upgrade 到 ≥ 2.3.0-preview.38(查通道指向用 npm view @sleep2agi/agent-network dist-tags)
5.5anet node start 打 ✅ started detached (tmux session live) exit 0,但 tmux ls 找不到 session、进程也不在detached 路径的假报;早于 2.3.0-preview.40 的版本有这个问题真判据:tmux has-session -t "=<alias>"; echo $? 应输出 0(= 必须)。批量场景用 anet project up(退出码在 ≥ 2.3.0-preview.40 上可信)。升级前,每次启动都用 has-session 复核
6claude-code-cli 节点起来后卡 offline / pane 卡在确认框Claude Code 的 --dangerously-load-development-channels 确认框等人按 Enter用 tmux 前台跑一次手动按 1 + Enter;后续就不弹了
7systemd / cron / 新用户启动报一连串 command not foundnvm + Bun 各自按用户装,非交互 shell 不加载把 node/npm/bun 软链到 /usr/local/bin/,或启动脚本里显式 source ~/.nvm/nvm.sh
8机器重启全部掉线hub + 节点都靠手动 tmux 挂着配 systemd 开机自启,参考 §8.2 systemd unit 里的模板

下一步 ​

如果踩到本页没覆盖的坑,欢迎到 GitHub Issues 开一条,写明哪一步、什么报错,附上 anet -v 输出。

Powered by Sleep2AGI

下载客户端