> ## Documentation Index
> Fetch the complete documentation index at: https://starforge.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# node 后端

> 裸机机器：forgelet daemon、共享盘、一作业一节点

适合几台 GPU 机器、又不想上 Kubernetes 或 Slurm 的场景。每台机器跑一个 `forgelet`
daemon；控制台通过一套很窄的 HTTP 接口投放作业——启动、观察、停止、日志、回收。

容器规格就是 `local` 构建的那一份。选卡和 `docker run` 都发生在机器上、在同一把锁之下，
而分配的事实来源仍然是容器标签。

<Warning>
  一个作业必须能装进**一个节点**。多节点 gang 调度没有实现，需要它的提交会在准入时被拒，
  而不是放到一半。
</Warning>

## 前置

1. 每台 GPU 机器：Docker + NVIDIA Container Toolkit
2. 共享存储在 console 和所有机器上挂**同一路径**（`FORGE_STORAGE_ROOT`）
3. console 上有一个 `node` [Fleet](/zh-Hans/ops/fleets) —— 在「Fleets → 新建 Fleet」里建，
   或首次启动时用 `FORGE_DEFAULT_FLEET_KIND=node` 种下

## 注册一台机器

注册是管理员做的事，不是用户。Fleet 页面会签出一个 join token，并给出一行可以直接
粘到机器上的命令：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -fsSL https://forge.corp/install.sh | FORGE_FLEET=<fleet> FORGE_JOIN_TOKEN=<token> sh
```

它会装上 `starforge-forgelet` 包、注册这台机器、并把 daemon 起起来。在已经装过
forgelet 的机器上再跑一遍，就是升级的方式。

如果机器上已经有这个包——重新加入，或者由配置管理装好的——同样的注册，不走安装器：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
forgelet join --server https://forge.corp --fleet <fleet> --token <token>
forgelet serve --port 7070
```

join token 就是全部授权：你需要的是这台机器的 root，而不是 console 上的账号。返回的是
这个节点的身份和一份凭证，写在 `FORGE_NODE_STATE_DIR` 下；`forgelet serve` 之后用它们
发心跳。

混卡不需要额外配置：节点在 join 时上报自己的卡，console 把卡名映射到硬件系列。注册表
不认识的卡会在 join 时报出来，好让管理员补进去——在那之前，指定了系列的作业不会落到
这台机器上。

## 节点配置

配在机器上，不是 console 上：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
FORGE_STORAGE_ROOT=/srv/starforge          # 与 console 同一路径
FORGE_LOCAL_GPU_COUNT=8                    # 0 表示用 nvidia-smi 探测
FORGE_NODE_STATE_DIR=~/.starforge-forgelet # 身份与凭证
```

把 `forgelet serve` 做成 systemd 服务。daemon 不跑训练，只起作业容器。

## Console 配置

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
FORGE_STORAGE_ROOT=/srv/starforge         # console 和节点同一路径
FORGE_NODE_REQUEST_TIMEOUT_S=15
FORGE_NODE_LAUNCH_TIMEOUT_S=120           # 镜像已在本地时的起容器超时；首次拉取是异步的
```

<Note>
  `FORGE_NODE_ADDRESSES` 和 `FORGE_NODE_TOKEN` 是在 console 自己的配置里点名一批节点。
  它们是注册之前的过渡路径，留给还没注册机器的部署；已经有注册节点的 Fleet 不会去读。
</Note>

## 语义

<AccordionGroup>
  <Accordion title="放置" icon="map-pin">
    卡型匹配、卡数够的节点里，挑空闲最多的。放不下就抛 `NoCapacity`，作业留在 `QUEUED`。
  </Accordion>

  <Accordion title="节点失联 ≠ 作业死亡" icon="unplug">
    打不到的节点上，observe 本轮不返回信号，对账跳过。节点回来后按真实容器状态收敛。失联期间这些卡在容量里记为 `blocked`。
  </Accordion>

  <Accordion title="拉镜像" icon="box">
    节点上第一次拉是异步的。作业停在 `PENDING`，带拉取说明。`FORGE_NODE_LAUNCH_TIMEOUT_S` 管的是镜像已在本地时的启动。
  </Accordion>

  <Accordion title="排空" icon="power-off">
    排空一个节点会停止新的放置，但不动正在跑的作业。机器要退出 Fleet 时用它，不必先杀掉工作。
  </Accordion>
</AccordionGroup>

更细的说明在仓库里的 `docs/ops/executor-backends.md`。
