---
date: 2026-05-18
tags: [gitea, actions, runner, scope, ops, non-admin]
---

# Gitea Actions runner：org owner 不需要 admin 也能加新 runner

## 背景

5/18 单台 dedicated-runner-1 扛不动 CI 队列（5+ runs queued、build 内 `Setup Node.js`
跑 8 分钟、`Install dependencies` 跑 19+ 分钟），要再加一台 runner。
我的账户 `chentao.jia` `is_admin: false`，第一反应是要找 admin 拿注册 token。

## 不直观的事

Gitea API 有 **三个并列的 registration-token 端点**，scope 不同，**权限要求也不同**：

| 端点 | 注册出的 runner scope | 谁能调 |
|---|---|---|
| `POST /api/v1/admin/runners/registration-token` | instance 级 | 仅 admin |
| `POST /api/v1/orgs/{org}/actions/runners/registration-token` | org 级（该 org 下所有 repo 共用） | **org owner**（不需要 admin） |
| `POST /api/v1/repos/{owner}/{repo}/actions/runners/registration-token` | repo 级 | **repo maintainer**（不需要 admin） |

而我作为 FFAIWorkspace 的 org owner，**直接走 org 端点就拿到 token，不需要找 admin**。

> 实测：401 是没权限，404 是路径错。我先撞 `/api/v1/admin/runners/registration-token`
> 返回 `404 page not found`——看起来像 endpoint 不存在，**其实是非 admin 调 admin 端点的伪装**。
> 改走 org 端点立刻 200 拿到 token。

注册出来的 runner 显示在 `GET /api/v1/orgs/{org}/actions/runners`，**不在
`/api/v1/admin/runners`**——这俩列表是不同 scope 的视图，不要以为 admin list 看不到
就是没注册成功。

## 解法（团队加 runner 的标准路径）

如果加 runner 服务 FFAIWorkspace 整个 org（推荐——所有 repo 共用）：

```bash
# 1. 拿 org-scoped 注册 token（org owner 即可）
TOKEN=$(curl -s -X POST -H "Authorization: token $GITEA_API_TOKEN" \
  http://43.130.59.228/api/v1/orgs/FFAIWorkspace/actions/runners/registration-token \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['token'])")

# 2. 在 runner 机注册（参考 docs/ops/02-gitea-config.md § 3）
/usr/local/bin/act_runner register \
  --instance http://43.130.59.228 \
  --token "$TOKEN" \
  --name <runner-name> \
  --labels ubuntu-latest:host,ubuntu-24.04:host \
  --no-interactive
```

如果只服务 workspace 一个 repo（历史选择，没必要再用）：

```bash
curl -s -X POST -H "Authorization: token $GITEA_API_TOKEN" \
  http://43.130.59.228/api/v1/repos/FFAIWorkspace/workspace/actions/runners/registration-token
```

如果一定要 instance 级（跨 org 共用，**仅 admin**）：找 admin 用户在 Web UI 生成
（Site Administration → Actions → Runners → Create new Runner）。

## 适用范围

- 加 runner 默认走 **org-scoped**——避免后续新 repo 又得加一遍 repo-scoped runner
- AI / 团队成员加 runner 不需要 ping admin，直接 org owner 一个人能完成

## 现状（2026-05-18）

加 `dedicated-runner-2` (43.166.182.155) 后的 runner topology：

| Name | Host | Scope | 状态 | 备注 |
|---|---|---|---|---|
| dedicated-runner-1 | 43.166.205.48 | repo (workspace) | online | 历史；可保留 |
| dedicated-runner-2 | 43.166.182.155 | **org (FFAIWorkspace)** | online | 2026-05-18 新加 |
| workspace-runner | 43.130.59.228 (Gitea 主机) | repo (workspace) | offline | 1.9G 内存兜底，永久 disable |
| uat-runner | UAT | org (FFAIWorkspace) | online | docker label，跑 backend-integration |

## 相关

- 部署细节：`docs/ops/02-gitea-config.md` § 3
- 加 runner 的另一面（SSH key 镜像）：本次同 PR 把 `~/.ssh/config` / `deploy_key` /
  `known_hosts` 从 .48 镜像到 .155，让新 runner 能接 deploy job
