存储、容器与 CI
独立 Evolver 的节点身份、资产、事件、mailbox、记忆和日志有不同的保存责任。先确定持久化布局,再将同一运行契约部署到服务、容器或 CI;Desktop 的内部目录由应用管理。
为数据选择保存方式
| 数据 | 长期实例 | 临时 CI |
|---|---|---|
| 身份与凭证 | 受保护存储,重启后保持归属 | 按任务需要从 secret manager 注入 |
| 资产与事件 | 持久卷并有一致性备份 | 按 job 隔离,按交付需要导出 |
| mailbox 与队列 | 保留在途状态,单实例协调写入 | 不复用其他 job 的可写运行状态 |
| 项目工作区 | 明确仓库、权限与恢复点 | 每个 job 独立 checkout |
| 日志 | 轮转并保留必要审计 | 导出脱敏结果,不缓存凭证 |
路径的具体优先级与目录参考见资产路径。多个实例不能仅凭节点 ID 相同就共享可写数据库或资产目录。
配置实例的启动环境
支持环境文件的入口使用 EVOLVER_ENV_FILE 或对应 --env-file 选择文件;该加载器用文件同名值覆盖传入环境。核对服务管理器、启动参数与文件,避免维护多套冲突配置。修改后重启对应进程。
用 evolver doctor 核对配置来源与连接,不输出完整进程环境。镜像只包含程序和非秘密依赖,凭证通过运行环境注入;身份与资产不能被打进公开镜像层。
示例:CI 中运行有限诊断
下面是 POSIX runner 的执行片段。由 CI 平台预先提供独立的 RUNNER_TEMP,安装所需 Node.js、Git 和 Evolver,并将需要的凭证注入受保护环境:
export EVOLVER_HOME="$RUNNER_TEMP/evolver-home"
export EVOLVER_TASK_RECEIVER=0
export EVOLVER_ATP_AUTOBUY=off
export EVOLVER_ATP_AUTODELIVER=off
evolver doctor
evolver cycle capabilities --json
这是环境与能力诊断,不执行进化任务或发布。需要执行的 job 另行声明仓库、材料、执行器、验证与超时;普通 CI 不启动无限循环。原始诊断报告含本地路径,上传前检查敏感信息。
示例:容器诊断与 GitHub Actions
在单独的示例目录保存下面的 Dockerfile。镜像安装 Node.js、Git 和 Evolver,以非 root 账号运行;默认命令只做诊断,不启动 Proxy、任务接收器或循环。
FROM node:22-bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN npm install --global @evomap/evolver \
&& mkdir -p /workspace /home/node/.evomap \
&& chown -R node:node /workspace /home/node/.evomap
ENV EVOLVER_HOME=/home/node/.evomap \
EVOMAP_HOME=/home/node/.evomap \
EVOLVER_TASK_RECEIVER=0 \
EVOLVER_ATP_AUTOBUY=off \
EVOLVER_ATP_AUTODELIVER=off
USER node
WORKDIR /workspace
VOLUME ["/home/node/.evomap"]
CMD ["evolver", "doctor"]
将示例目录作为构建上下文,只挂载允许检查的非敏感示例项目。以下命令适用于 POSIX shell;PowerShell 使用实际绝对路径替换 source=$PWD 部分。
docker build -t evolver-tools .
docker volume create evolver-example-home
docker run --rm \
--mount type=volume,source=evolver-example-home,target=/home/node/.evomap \
--mount "type=bind,source=$PWD,target=/workspace,readonly" \
evolver-tools
docker run --rm \
--mount type=volume,source=evolver-example-home,target=/home/node/.evomap \
--mount "type=bind,source=$PWD,target=/workspace,readonly" \
evolver-tools evolver cycle capabilities --json
两个容器顺序使用同一卷,分别核对 doctor 与 capabilities 的输出。独立实例使用不同卷;不要让两个常驻写入者共享这个卷。源码只读挂载适用于本例诊断;执行修复需要单独授权的可写工作区,不能简单移除只读限制后运行任意任务。
镜像内不配置节点 secret。需要联网的实例通过运行平台的 secret store 或只读环境文件挂载取得凭证,不把凭证 COPY 进镜像。已有卷权限错误时核对镜像账号 UID、目录所有者和挂载点,不使用全局可写权限解决。
下面保存为 .github/workflows/evolver-diagnostics.yml,通过 workflow_dispatch 手动运行:
name: Evolver diagnostics
on:
workflow_dispatch:
permissions:
contents: read
jobs:
diagnose:
runs-on: ubuntu-latest
timeout-minutes: 5
env:
EVOLVER_HOME: ${{ runner.temp }}/evolver-${{ github.run_id }}-${{ github.run_attempt }}
EVOMAP_HOME: ${{ runner.temp }}/evolver-${{ github.run_id }}-${{ github.run_attempt }}
EVOLVER_TASK_RECEIVER: "0"
EVOLVER_ATP_AUTOBUY: "off"
EVOLVER_ATP_AUTODELIVER: "off"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install Evolver
run: npm install --global @evomap/evolver
- name: Inspect the isolated runtime
shell: bash
run: |
set -euo pipefail
mkdir -p "$EVOLVER_HOME"
git status --short --branch
evolver doctor
evolver cycle capabilities --json
这份工作流每次使用独立运行目录,只做本地诊断与能力检查,不执行进化、领取任务或发布。npm 安装会访问包仓库;诊断通过不代表业务任务已经执行。doctor 失败时保留失败结果,修复对应配置后重新运行,不设置 continue-on-error 来掩盖失败。
用于可复现交付时,将全局安装改为仓库管理的本地依赖,使用审核通过的精确版本,提交 package.json 与依赖锁文件,通过 npm ci 安装,并调用已安装的 node_modules/.bin/evolver。npm 全局安装不读取项目锁文件。容器中把这两份依赖清单复制到独立工具目录,在该目录执行 npm ci 并使用本地可执行文件。基础镜像与 Actions 固定到已审核的不可变摘要或提交 SHA。运行前完成这些输入的解析与审核;上面的诊断示例使用包仓库与标签解析,不提供可复现的依赖图。
接入业务 CI 时,单独增加项目材料、执行器、验证命令与产物检查,并按仓库交付标准运行。复用依赖缓存不包括整个 Evolver home;需要保留资产时先按同步与导出流程生成无凭证归档。容器的持久化与重启检查步骤见下节。
容器与重启验收
- 使用非特权运行用户,挂载独立的可写运行目录,源码与秘密按实际需要提供最小访问范围。
- 在实例中创建或导入一组允许保存的资产,记录 ID 与数量。
- 停止写入后重启容器,核对节点、资产、引用和未完成队列。
- 启动第二个实例时提供独立目录,确认不会重复消费同一队列。
- 恢复演练核对实际内容,不只检查卷已挂载。
运行账号必须能读写自己的持久化目录,不能为解决权限错误而让所有实例共享无限制目录。部署细节见容器与 CI,持续进程的接入与停止见任务队列。