Nullboard 2023.11.05 配置参数详解

Nullboard 全量配置项详解:前端 AppConfig 字段(源码溯源)、localStorage 键结构、nbagent 命令行参数与 app-config.json、备份目录 rev 文件命名规则,实测+溯源双口径。

Nullboard看板配置2026/10/24

Nullboard 2023.11.05 配置参数详解

目标:把 Nullboard 的全部可配置项一次讲透——前端应用配置(AppConfig/localStorage)、备份 Agent(nbagent 1.1.0)的命令行参数与配置文件、备份存储的目录与文件命名规则。前端字段以 nullboard.html 源码(master 分支,codeVersion 20231105)溯源并标注行号;Agent 侧参数与文件内容均在 Ubuntu 22.04 + nbagent 1.1.0 环境实测取证。

一、环境信息

项目取值
前端应用Nullboard nullboard.html,master 分支,codeVersion 20231105(2023.11.05),105597 字节
前端字段溯源nullboard.html 源码(AppConfig 类 L1727-L1750、default_backup_agents L1752-L1756、BoardMeta 类 L1760-L1767)
备份 Agentnbagent 1.1.0(PyPI,Python 3.10.12 实测)
Agent 数据目录/var/lib/nbagent/(本文实测口径)
操作系统Ubuntu 22.04(Nginx 1.18.0 静态托管主页面)

阅读前提:Nullboard 的配置分散在「浏览器端」与「Agent 端」两处,二者通过备份协议(PUT /config)同步。改配置前先想清楚改的是哪一侧:界面外观/行为参数在浏览器端,监听/存储/token 在 Agent 端。

二、前置条件

systemctl is-active nbagent
ss -ltn | grep 10001

实测回显:

active
LISTEN 0      128          0.0.0.0:10001      0.0.0.0:*
  • 掌握 Agent 的 Access Token(配对凭据,读自数据目录的 app-config.json):
python3 -c "import json;print(json.load(open('/var/lib/nbagent/app-config.json'))['auth'])"

实测回显:

46f95cf448a24a96b1f4c7c7ed5eb369

(token 为部署时随机生成,读者环境取自己的值即可。)

三、参数查看与修改方式

Nullboard 的配置有三条查看/修改链路,各有覆盖面与生效方式:

链路覆盖范围修改入口生效方式
浏览器 UI 偏好菜单主题、字体、字号、行高、列表宽度看板右上菜单 → UI preferences即改即存(localStorage)
浏览器 localStorage全部 AppConfig 字段 + 看板数据开发者工具 Console 读写 localStorage刷新页面生效
Agent 配置文件Agent 的 auth/conf编辑 app-config.json 或通过备份协议 PUT /config重启 Agent / 协议写入即生效

说明:UI 菜单只暴露了少量高频项(主题/字体/字号/行高/列表宽度);maxUndo、fileLinks 等字段未进 UI,需走 localStorage 或备份链路。备份 Agent 配置中由 Nullboard 保存的 conf 字段是前端配置的完整快照——当换浏览器时,Agent 侧快照可用于核对(nbagent 本身不向前端下发配置,恢复配置以导出/备份文件为准)。

四、参数总览

4.1 前端 AppConfig 参数(浏览器端)

字段定义溯源:nullboard.html 源码 AppConfig 构造函数(L1727-L1750),下表「默认值」列即源码字面值:

参数类型默认值含义
verLastnumber/nullnull最近使用过的 codeVersion(升级提示用)
verSeennumber/nullnull最近看过 changelog 提示的 codeVersion
maxUndonumber50每块看板保留的撤销修订数(官方 README 注明 "configurable in the code")
fontNamestring/nullnull字体族;null = 默认 Barlow
fontSizenumber/nullnull字号;未设置时按 fsize 档位取值(z1 档为 13)
lineHeightnumber/nullnull行高;未设置时按 fsize 档位取值(z1 档为 17)
listWidthnumber/nullnull列表列宽
themestring/nullnull主题:null/default 浅色,dark 深色
fileLinksbooleanfalse是否把 `foo` 文本标记为 file:///foo 本地文件链接(2021.08.04 changelog 引入)
boardnumber/nullnull上次活动的看板 ID(恢复上次视图)
backupsobject{agents:[], nextId:1}备份 Agent 配置数组与 ID 分配器(见 5.3)
backupStatusobject{}各 Agent 备份状态(agentId => 状态数组)

表格解读:前端参数里只有 fontSize/lineHeight/listWidth/theme/fontName 五项在 UI 菜单可改;其余字段或为系统维护值(verLast/verSeen/board/backupStatus),或需进 localStorage 修改(maxUndo/fileLinks)。

4.2 nbagent 命令行参数(Agent 端)

nbagent --help 实测回显(nbagent 1.1.0):

Usage: nbagent [OPTIONS]

  A Nullboard backup agent

Options:
  --addr TEXT            Bind to address  [default: 0.0.0.0]
  --port INTEGER         Use custom port  [default: 10001]
  --data TEXT            Directory for data  [default:
                         /root/.local/share/nbagent]
  --reset-token          Generate a new random auth token
  --override-token TEXT  Use a custom auth token
  --help                 Show this message and exit.

注:--data 默认值随 $HOME/XDG_DATA_HOME 展开,上文回显为本机 root 环境实测;源码默认逻辑为 $XDG_DATA_HOME/nbagent,未设时取 $HOME/.local/share/nbagent(nbagent 源码 main.py L24-L27)。

4.3 备份存储结构(Agent 端落盘规则)

路径/文件内容命名规则
<data>/app-config.jsonAgent 自身配置(auth/conf)固定名
<data>/boards/<board_id>/在用看板备份目录名 = 看板内部数字 ID(如 1618401166671)
<data>/boards/<board_id>/rev-XXXXXXXX.json看板某次修订的完整数据rev-{revision:08}.json,按备份数据里的 revision 字段 8 位零填充
<data>/boards/<board_id>/meta.json看板修订元数据(current/history/undo 等)固定名
<data>/deleted/<board_id>/已删除看板的备份(nukeBoard 后由 rename 迁入)同上

五、核心参数分类详解

5.1 界面外观参数(fontSize / lineHeight / listWidth / theme / fontName)

这五个参数决定看板的阅读体验,全部可在浏览器 UI 偏好菜单调整(菜单里以字号档位、行高/列宽滑杆呈现)。源码溯源:初次初始化时按 fsize 档位赋默认值(nullboard.html L2297-L2301):

if (this.getItem('fsize') == 'z1')
{
    this.conf.fontSize   = 13;
    this.conf.lineHeight = 17;
}

即默认档位对应 字号 13 / 行高 17;fontName 默认 null 表示用内置 Barlow 字体;theme 取 default 或 dark(深色主题于 2020.02.19 changelog 引入)。

如何验证生效:修改后可在浏览器开发者工具 Console 里读取快照核对:

JSON.parse(localStorage.getItem('nullboard.config'))

(返回 AppConfig 全量 JSON,各字段见 4.1 表。)

  • maxUndo = 50:每块看板在浏览器里保留的修订数上限,超出后最旧修订被丢弃。官方 README 明示 "Undo/redo for 50 revisions per board (configurable in the code)"——它不在 UI 菜单中,调整需在 Console 里改写 localStorage 后刷新:
var c = JSON.parse(localStorage.getItem('nullboard.config'));
c.maxUndo = 100;
localStorage.setItem('nullboard.config', JSON.stringify(c));
  • fileLinks = false:默认关闭。开启后笔记里 `foo` 形态的文本会被渲染为指向 file:///foo 的链接(配合 CapsLock 高亮/点击),适合本机文件索引场景;浏览器对 file:// 协议有安全限制,远程访问场景不建议开启。
  • board:记录上次活动看板 ID,刷新页面后自动回到该看板,属系统维护字段,无需手工干预。

5.3 备份配置参数(backups.agents / nextId / backupStatus)

备份相关配置集中在 AppConfig.backups,源码溯源(L1743-L1756):

this.backups      =
{
    agents : [ ],               // [ { type, id, enabled, conf } ];
    nextId : 1
};
...
const default_backup_agents =
[
    { base: 'http://127.0.0.1:10001', auth: '' }, // local agent
    { base: '', auth: '' }                        // remote agent
];

参数逐项说明:

  • agents:已配置的备份 Agent 列表,每项含四个字段——type(simp = SimpleBackup 协议)、id(nextId 分配的数字)、enabled(是否启用)、conf(该 Agent 的连接配置,含 base 服务地址与 auth Access Token)。默认预置两条:本地 Agent http://127.0.0.1:10001 与一条空的远程 Agent 条目;
  • nextId:下一个 Agent 的 ID 分配计数器;
  • backupStatus:运行时状态(agentId => 当前已备份到哪些修订),配对成功后由应用自动维护。

修改入口:UI 的 Auto-backups 对话框(填 base 地址 + Access Token → Check the setup → Save),Save 后应用会把整份 AppConfig(含 backups)通过 PUT /config 同步给 Agent 存档。

5.4 nbagent 命令行参数逐项

五个参数逐项说明(默认值来自 4.2 节实测 --help 回显与源码常量):

  • --addr(默认 0.0.0.0):监听地址。生产建议收紧为 127.0.0.1(Agent 只服务本机浏览器时)或内网网卡地址,避免 10001 端口暴露到公网;
  • --port(默认 10001):监听端口,与 Nullboard 配置里的 Agent base 地址端口一致;多实例场景用不同端口区分;
  • --data(默认 $XDG_DATA_HOME/nbagent,即 root 下 /root/.local/share/nbagent):数据目录。服务器级部署建议显式指定(本文用 /var/lib/nbagent),目录不存在时自动创建 boards/ 与 deleted/ 子目录;
  • --reset-token:标志参数,把 Access Token 重置为新随机值(uuid4 去连字符)并写回 app-config.json;token 变了浏览器端要重新配对;
  • --override-token TEXT:以指定字符串覆盖 token(适合 scripted 部署固定 token)。两个 token 参数可并存,override 优先写入。

实测:override 后 token 立即生效(为不干扰已运行的主 Agent,示例另用 --port 19999 与独立数据目录 /tmp/nbtest):

nbagent --override-token 9f2c7b1e5a8d4f30aa11bb22cc33dd44 --data /tmp/nbtest --port 19999 &
sleep 2; cat /tmp/nbtest/app-config.json; kill %1

实测回显:

 * [i] Using data directory /tmp/nbtest
 * [i] Config saved to /tmp/nbtest/app-config.json
 * [!] Nullboard token: 9f2c7b1e5a8d4f30aa11bb22cc33dd44
 * [i] Server listening 0.0.0.0:19999...
 * Serving Flask app 'nbagent.main'
 * Debug mode: off
{
  "auth": "9f2c7b1e5a8d4f30aa11bb22cc33dd44"
}

结果确认:app-config.json 的 auth 即 override 指定值。

5.5 nbagent 配置文件 app-config.json

Agent 的配置就一个 JSON 文件,含两个字段(实测逐字段):

{
  "auth": "46f95cf448a24a96b1f4c7c7ed5eb369",
  "conf": "{\"maxUndo\":50,\"theme\":\"dark\",\"fontSize\":14,\"lineHeight\":19,\"listWidth\":null,\"fileLinks\":false,\"backups\":{\"agents\":[],\"nextId\":3}}"
}
  • auth:Access Token,所有备份请求须带头 X-Access-Token: <auth>,不匹配返回 401(实测 wrong-token 请求回显 HTTP/1.1 401 UNAUTHORIZED,响应体为 Werkzeug 标准错误页);
  • conf:前端 AppConfig 的完整 JSON 快照(字符串化)。由 Nullboard 在「Auto-backups 保存」时经 PUT /config 写入;nbagent 收到后原样存储(源码 main.py L138-L144:CONFIG["conf"] = conf 后 write_config())。

修改方式与生效:手改该文件后需 systemctl restart nbagent;经协议写入则即时落盘。实测一次协议写入的前后对照(PUT /config 携带 conf 表单字段):

写入前:

{
  "auth": "46f95cf448a24a96b1f4c7c7ed5eb369",
  "conf": "{\"darkMode\":false}"
}

执行 curl -s --noproxy "*" -X PUT http://127.0.0.1:10001/config -H "X-Access-Token: $TOKEN" -d "self=http://192.168.31.10/nullboard.html" --data-urlencode "conf={\"maxUndo\":50,\"theme\":\"dark\",...}" 返回 true 后:

{
  "auth": "46f95cf448a24a96b1f4c7c7ed5eb369",
  "conf": "{\"maxUndo\":50,\"theme\":\"dark\",\"fontSize\":14,\"lineHeight\":19,\"listWidth\":null,\"fileLinks\":false,\"backups\":{\"agents\":[],\"nextId\":3}}"
}

重启 Agent 后再次查看,conf 内容原样保留(实测 systemctl restart nbagent 后 cat 输出与写入后一致),即 conf 快照跨重启持久。

5.6 备份存储目录与文件命名(rev-XXXXXXXX.json)

nbagent 收到 saveBoard 后的落盘规则(源码常量 REV_FILE_PATTERN = "rev-{0:08}.json",main.py L16;revision 取自请求表单 data 字段 JSON 内的 revision 键,main.py L111):

/var/lib/nbagent/boards/1618401166671/meta.json
/var/lib/nbagent/boards/1618401166671/rev-00000000.json
/var/lib/nbagent/boards/1618401166671/rev-00000003.json
/var/lib/nbagent/boards/1618401166671/rev-00000005.json
  • 目录名 1618401166671 为 Nullboard 看板内部 ID(毫秒时间戳风格);
  • rev-00000003.json 即 revision 3 的完整看板数据,内容为纯 JSON(实测示例):
{
  "title": "Ops Board",
  "lists": []
}
  • meta.json 保存修订元数据(实测示例):
{
  "revision": 5,
  "undo": []
}
  • rev 文件按 revision 命名且同名覆盖:同一 revision 反复备份只保留最后一份;不同 revision 各占一个文件(上例 0/3/5 并存即实测所得);
  • 看板在 Nullboard 里被删除时,浏览器端会发 DELETE /board/<id>,Agent 把 boards/<id>/ 整目录 rename 到 deleted/<id>/(实测删除后 deleted/1618401166671/ 出现,内含原 meta.json 与 rev 文件)。

六、生产配置模板

以下模板面向「内网固定入口 + 单机备份」的生产形态(2 核 4GB、内网隔离、个人/小团队使用),可直接套用:

Agent systemd 单元(/etc/systemd/system/nbagent.service):

[Unit]
Description=Nullboard Backup Agent (nbagent)
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/nbagent --addr 0.0.0.0 --port 10001 --data /var/lib/nbagent
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target

参数取舍说明:

  • --addr 0.0.0.0:内网用户需要从各自浏览器直连 Agent 备份,故监听全网卡;若仅本机浏览器使用,收紧为 --addr 127.0.0.1;
  • --data /var/lib/nbagent:脱离 $HOME,便于对 /var/lib/nbagent 做整目录二次备份(cron rsync 等);
  • 无需 JVM/内存参数(Python Flask 常驻内存实测约 30-40MB 量级,无需专门调优);
  • token 管理二选一:固定 token 用 --override-token <值>(写进 unit 前先 chmod 600 该 unit),或保持随机生成、部署时人工抄录配对。

前端建议配置(Auto-backups 对话框 + Console):

  • backups.agents[0].conf.base = http://<服务器IP>:10001、auth = <Agent token>、enabled = true;
  • 个人高频编辑用户可在 Console 把 maxUndo 调到 100 以上(每修订都是整看板快照,localStorage 5-10MB 配额下 50 默认值对超大看板可能吃紧,出现存储告警时优先调回小值或勤导出 .nbx)。

七、常见问题

Q1:改了 app-config.json 的 conf,为什么浏览器里的设置没变? conf 是 Agent 侧的「存档快照」,nbagent 不会把它下发回浏览器;浏览器端以自己 localStorage 为准。它的价值是灾备核对与审计,不是同步源。要改前端配置请在浏览器端改(UI 菜单或 localStorage)。

Q2:备份接口返回 401? X-Access-Token 与 app-config.json 的 auth 不匹配。核对浏览器 Auto-backups 里粘贴的 token 与 Agent 当前 token 是否一致(Agent 侧 --reset-token 后浏览器必须重新配对);请求测试时注意 token 前后不要带空格。

Q3:rev 文件名不递增,总是 rev-00000000.json? rev 号取自备份数据 JSON 内的 revision 字段(非 meta 字段)。手工模拟备份时若 data 里不带 revision,一律落到 rev-00000000.json——这是 nbagent 源码逻辑(data.get("revision", "0")),真实浏览器场景下 Nullboard 每次修改都会递增 revision,无需干预。

Q4:删除了一块看板,Agent 备份还在吗? 在,但移到了 deleted/<board_id>/。nukeBoard 的实现是目录 rename 而非物理删除(源码 main.py L125-L135),磁盘上的 rev 文件可手工取回导入;deleted/ 目录需定期人工清理,否则只增不减。

Q5:重复 DELETE 同一块看板会怎样? 实测对不存在(或已删除)的看板 ID 执行 DELETE /board/9999999999999,HTTP 仍返回 200 但响应体为 false,且 Agent 日志报 Error renaming ...。Nullboard 以响应体判断成败,false 表示该次 nuke 未生效,属预期行为而非故障。

Q6:localStorage 配额满了会怎样? 单站点 localStorage 通常 5-10MB,超限时 Nullboard 写配置失败(源码 setJson 返回 false 分支)并提示。对策:控制单看板规模、调低 maxUndo、及时用 Export board 把旧看板归档为 .nbx 后删除。

八、参考链接