跳转到主要内容
当宿主机无法提供 systemd user session 时,可以使用社区维护的 Docker 封装运行 Orbi。 仓库里的 Docker 部署外挂 3rd/docker/ 是社区维护、非官方支持的薄封装:一个 Linux 容器,跑的是未改动的 官方部署——systemd 作为 PID 1 带真实 user manager、官方 systemd/[email protected] + [email protected] user unit、可编辑 CLI 安装和 幂等的 orbi setup。它不是第二套部署模型:有 systemd user session 的 Linux 主机请始终优先走官方路径 (见快速开始)——两条路径二选一,不要对同一个 任务池并存。

什么时候用它

  • 宿主机没有 user systemd session(NAS、容器平台、受限的云主机)但 能跑 Docker。
  • 想把 runner 与宿主机用户会话隔离。

快速开始

拉取发布镜像,然后用一条 docker run 启动 runner。两个仓库源携带 相同 tag:latest 和去掉 v 前缀的发布号(如 0.5.17)。
一条 docker run 即可达成交付:GitHub token、任务池和模型 provider 全部来自环境变量,entrypoint 在首次启动时把它们写进 deploy home 的 env 文件、生成的 orbi.toml 和生成的 pi-providers.json(已存在的 文件绝不覆盖)。替换三个带引号的值——token、repo、key;DeepSeek 端点只是示例,任何 OpenAI 兼容端点都用同样四个变量 (ORBI_PI_PROVIDER、ORBI_PI_MODEL、ORBI_PI_BASE_URL、 ORBI_PI_API_KEY)。从 Docker Hub 拉取的话,把镜像引用换成 docker.io/orbibuild/orbi:latest。
一条 docker run,不需要 compose(runner 是单一服务)。 --cgroupns=host 加 /sys/fs/cgroup 读写 bind 让 systemd 能以 PID 1 身份在容器内运行——默认 private cgroupns 下创建 /init.scope 会失败(已实证;无需 --privileged)。全部状态(orbi checkout、 配置、运行时状态、交付 checkout 与 worktree)都在两个 volume 里, 容器重建不丢,幂等 setup 在下次启动时重新收敛。

配置如何到达 runner

完整契约——生成的配置、日常操作、故障与修复表——见 3rd/docker/README.md。

第一次交付

runner 跑起来之后,交付一个真实任务:
  1. 在任务池仓库开一个 Issue,用两种形状之一陈述一个可观测的运行时 结果:修复(when X, should Y, actually Z)或变更(when X, the user should be able to Y; today they cannot because Z)。
  2. 打上 ai-ready label(首次启动已创建十二个平台 label)。
  3. 跟踪 tick 日志:
两个 tick 内(timer 每 5 分钟触发一次)Issue 会走完 ai-ready → ai-in-progress → ai-pr-opened 并开出 PR;独立评审 一轮后合并(ai-merged)。整条路径不需要任何 docker exec 配置 步骤——哪一步需要手工 exec,就是文档或 entrypoint 的缺陷。

Orbi 快速指南

交付所需的基本概念集中在一页;完整参考用链接给出,不在页内重复。
  • 任务长什么样 — 一个 Issue 用两种形状之一陈述一个可观测的运行 时结果:修复(when X, should Y, actually Z)或变更(when X, the user should be able to Y; today they cannot because Z),附一小份 验收清单:用户旅程按前置条件 → 命令/配置 → 用户看到的成功结果 → 失败路径与修复展开。
  • label 含义 — ai-ready 是执行开关:runner 只认领带这个 label 的 Issue(认领顺序:p0 优先,其次 bug,再普通 Issue)。被认领 后走 ai-in-progress → ai-pr-opened → ai-merged(终态;PR 描述 里的 Fixes #N 会自动关闭 Issue)或 ai-fix-needed(下一轮评审 修复发现的问题);ai-blocked(终态)需要人来决策。ai-epic 标记 纯协调 Issue,runner 永不认领;ai-release 标记发布任务(见下)。 交付状态由 runner 管理;ai-ready、ai-epic、ai-release、 p0、bug 由你来打和摘。
  • 怎么看进度 — 每次运行在 Issue 上只保留一条进度评论,每个 里程碑原位更新;tick 日志用上面的 journalctl 命令实时跟踪。
  • 预期结果 — 两个 tick 内出现分支和 PR(描述带 Fixes #N), 随后独立评审会话运行(最多 5 轮),合并落在被评审的那个 commit 上——之后 GitHub 自动关闭 Issue。
  • 如何发布 — 发布是独立的 Issue:打 ai-ready + ai-release 两个 label,正文声明 ## Release 块:version、base_branch, 以及 scope(#N 列表)或 scope_from_milestone。Runner 的发布 状态机冻结 base、等待 CI 全绿、升版本号、打 tag、发布 GitHub Release 并关闭对应 Milestone——全程没有 PR;任何失败停在 ai-blocked,由人决策。
完整参考:Workflow(label、评审循环、发布状态机)与 Operations(可观测性、journal)。

日常操作

容器内命令一律以 -u orbi 执行(runner 就是以该用户跑的); systemctl --user / journalctl --user 依赖用户会话总线,docker exec 不会自动带上,需要 -e XDG_RUNTIME_DIR=/run/user/1000。orbi CLI 装在 orbi 用户的 ~/.local/bin,不在 docker exec 的默认 PATH 里——所以 套一层 bash -c(docker exec 会为 -u 用户设置 HOME)。 升级:docker pull 新 tag 后用同样的 volume 和变量重建容器——状态在 volume 里,entrypoint 与 orbi setup 幂等收敛。

从源码构建

需要改动封装本身(entrypoint、setup oneshot、Dockerfile)时,从仓库 checkout 构建镜像,而不是拉取:
然后按快速开始同样的 docker run 运行,镜像名换成 orbi-docker。 镜像内不含任何凭据——配置按上表在 docker run 时注入。

进阶:多 provider

快速开始从环境变量配置一个 provider。要同时服务多个 (如 deepseek 加 groq):
  1. 启动时用 ORBI_ENV_<NAME>(可重复)注入额外的 key: -e ORBI_ENV_GROQ_API_KEY="gsk-xxx" 落进 /orbi/.orbi/env 为 GROQ_API_KEY;
  2. 编辑 /orbi/.orbi/pi-providers.json——entrypoint 首次启动生成了 单 provider 版本且绝不覆盖已有文件——加入其余 provider,每个 apiKey 引用自己的环境变量("$GROQ_API_KEY");
  3. 把 /orbi/orbi.toml 里的 pi_provider / pi_model 指向要用的 provider 与 model,然后重启容器:docker restart orbi(两个文件 都是你的——entrypoint 绝不覆盖已有配置)。
首次启动完全没有 provider 变量时不会生成 pi-providers.json; orbi setup 会生成 starter 文件供填写。依赖某个端点前先验证:
返回真实 API 回复即端点与 key 可用;401/超时就是 key 或网络问题。

边界

  • 只做薄封装:不碰 src/orbi/ 核心代码,容器内撞到的阻塞性问题另开 核心 Issue。
  • 仅 Linux;不做 compose、多容器编排、镜像自动更新;不进 PyPI 发布 包、不进 getting-started 主路径。
  • 社区维护:官方 Issue 优先处理核心 systemd 路径。