CryptPad 2026.5.1 常用 CLI 命令与工具详解
CryptPad 2026.5.1 服务端 CLI 全量实测:npm 启动/构建命令、evict 清理与归档恢复脚本、用量统计 CSV、支持邮箱密钥生成、定时任务编排,含三个脚本的本版本真实缺陷实录。
CryptPad 2026.5.1 常用 CLI 命令与工具详解
目标:把 CryptPad 2026.5.1 服务端可用的全部命令行工具——服务启动/构建命令、
scripts/目录下的数据治理与管理脚本、定时任务编排——逐条讲清用法并附实测回显。所有命令与输出均在 2026.5.1 实例上真实执行验证(实例搭建见 《CryptPad 2026.5.1 Docker Compose 部署指南》,其中已含三个脚本在本版本的真实缺陷实录)。
一、环境信息
- 实例版本:CryptPad 2026.5.1(版本标签
version-2026.5.1,运行时 Node.js v24.16.0); - 命令执行位置:统一为 CryptPad 安装目录
/opt/cryptpad/(源码安装官方推荐创建专用运行用户并以其身份执行,下文命令均在该目录下运行); - 脚本取证目录:
/opt/cryptpad/scripts/(2026.5.1 实测共 27 个条目,本文覆盖运维常用的 13 个); - 实测时间:2026-10-22。
二、工具概览
CryptPad 的服务端 CLI 由三层构成:
| 层 | 工具 | 用途 |
|---|---|---|
| 服务进程 | npm start(等价 node server.js)及 dev/fresh/offline 变体 | 启动/开发/强制重建启动 |
| 数据治理脚本 | scripts/evict-inactive.js、evict-archived.js、expire-channels.js、restore-archived.js、user-statistics.js、check-account-deletion.js、clear.js | 不活跃清理、归档清理与恢复、用量统计、账户核查、全库清空 |
| 管理与诊断脚本 | scripts/generate-admin-keys.js、install.js、pinned.js、testcrypto.js、diagnose-archive-conflicts.js、issue-jwt.js | 支持邮箱密钥、安装令牌、钉存统计、加密自检、归档冲突诊断、JWT 调试 |
脚本执行约定:cd /opt/cryptpad && node scripts/<脚本名>.js——脚本内部按相对路径加载 ../lib 与配置(../config/config.js),必须在安装目录下执行,否则配置加载失败。
三、前置条件
- 实例已部署并可启动(部署流程见部署指南篇);
- 以实例运行用户身份执行(源码安装为专用用户;对安装目录有读写权限,否则 5.5 的 CSV 输出会报
EACCES); - 数据治理脚本直接增删安装目录下的数据文件,生产执行前先备份
datastore/、data/、blob/、block/四个目录; - 清理类脚本与服务进程共享数据目录,官方架构为「服务端内置定时清理(
disableIntegratedEviction默认 false)」,手动执行主要用于关闭内置清理的实例或紧急回收。
四、服务启动与构建命令
4.1 npm scripts 全量清单(package.json 实查原值)
{
"install:components": "node scripts/copy-components.js",
"start": "node server.js",
"dev": "DEV=1 node server.js",
"windev": "set DEV=1& node server.js",
"fresh": "FRESH=1 node server.js",
"offline": "FRESH=1 OFFLINE=1 node server.js",
"offlinedev": "DEV=1 OFFLINE=1 node server.js",
"package": "PACKAGE=1 node server.js",
"lint": "eslint . && stylelint \"./customize.dist/src/less2/**/*.less\"",
"lint:debug": "DEBUG=eslint:* eslint .",
"lint:js": "eslint .",
"lint:less": "stylelint \"./customize.dist/src/less2/**/*.less\"",
"lint:translations": "node ./scripts/translations/lint-translations.js",
"unused-translations": "node ./scripts/translations/unused-translations.js",
"test": "node scripts/TestSelenium.js",
"test-rpc": "cd scripts/tests && node test-rpc",
"evict-inactive": "node scripts/evict-inactive.js",
"build": "node scripts/build.js",
"clear": "node scripts/clear.js",
"installtoken": "node scripts/install.js",
"api": "rollup -c"
}
要点解读:start 为生产启动;dev 开 DEV=1(开发模式,禁用部分缓存);fresh 开 FRESH=1 强制完整重建前端产物;offline 再叠加 OFFLINE=1(离线可用资源打包);build 即启动时执行的构建;evict-inactive/clear/installtoken 三个 npm 入口与直接 node scripts/… 等价;test 需要浏览器环境(Selenium),服务器上一般不用。
4.2 前台启动与首启日志
cd /opt/cryptpad && npm start
实测首启日志(节选,完整解读见部署指南篇 4.4):
> cryptpad@2026.5.1 start
> node server.js
=============================
Create your first admin account and customize your instance by visiting
http://localhost:8145/install/#669ba14a5387634fd1086d5689c9dfa24b64006e283fbb1eab4fc1d3590fa986
=============================
配置文件语法错误时的实测表现(lib/load-config.js 行为):进程打印 config/config.js is faulty. ... Terminating. 后退出,脚本排障先跑 node -e "require('./config/config.js')" 预检。
五、数据治理脚本详解
5.1 evict-inactive.js(不活跃数据清理)
清理「未被任何注册用户钉住且超过 inactiveTime(默认 90 天)」的文档、文件块与闲置账户数据。官方 config 注释原文明确:服务端自 3.23.0 起内置自动清理,脚本形态用于手动执行或关闭内置清理后的 crontab 定时执行。
实测执行(空实例):
cd /opt/cryptpad && node scripts/evict-inactive.js
echo "exit=$?"
exit=0
控制台无输出——脚本把执行报告写进 NDJSON 磁盘日志(logPath 下按 UTC 日期分目录)。实测日志文件 data/logs/26/262026-10-21T21:16:29.060Z.ndjson 全文:
["INFO","2026-10-21T21:16:29.069Z","EVICT_CHANNEL_ACTIVITY_START","Assessing channel activity"]
["INFO","2026-10-21T21:16:29.070Z","EVICT_CHANNELS_CATEGORIZED",{"active":0,"channels":0}]
["INFO","2026-10-21T21:16:29.078Z","EVICT_BLOBS_ACTIVITY_START","Assessing blob activity"]
["INFO","2026-10-21T21:16:29.078Z","EVICT_BLOBS_CATEGORIZED",{"active":0,"blobs":0}]
["INFO","2026-10-21T21:16:29.084Z","EVICT_ACCOUNTS_ACTIVITY_START","Assessing account activity"]
["INFO","2026-10-21T21:16:29.086Z","EVICT_COUNT_ACCOUNTS",{"accounts":0,"inactive":0}]
["INFO","2026-10-21T21:16:29.086Z","EVICT_BLOB_START",{}]
["INFO","2026-10-21T21:16:29.087Z","EVICT_BLOBS_REMOVED",0]
["INFO","2026-10-21T21:16:29.099Z","EVICT_INACTIVE_CHANNELS_START",{}]
["INFO","2026-10-21T21:16:29.099Z","EVICT_CHANNELS_ARCHIVED",{"channels":0,"archived":0}]
["INFO","2026-10-21T21:16:29.099Z","EVICT_TIME_TO_RUN_SCRIPT",30]
["INFO","2026-10-21T21:16:29.100Z","EVICT_INACTIVE_FINAL_REPORT",{"launchTime":1792617389069,"activeChannels":0,"totalChannels":0,"totalBlobs":0,"activeBlobs":0,"totalAccounts":0,"activeAccounts":0,"channelsArchived":0,"runningTime":30}]
试运行(DRY RUN):脚本头注释写「Set DRY_RUN to true to run the script without deleting anything」,但 2026.5.1 源码第 20 行为硬编码 Env.DRY_RUN = false;——要试运行必须先编辑该行改为 true(本版本无环境变量开关,实测确认环境变量 DRY_RUN=1 方式无效)。试运行只记录「将删除什么」到日志,不落删除。
5.2 evict-archived.js(归档区清理)
把 archivePath(默认 data/archive)中超过 archiveRetentionTime 的归档数据永久删除。官方 config 注释原文:「cryptpad/scripts/evict-archived.js is intended to be run daily from a crontab or similar scheduling service」——即官方设计为每日定时执行。实测(空归档区):
cd /opt/cryptpad && node scripts/evict-archived.js
echo "exit=$?"
exit=0
与 5.1 同款行为:控制台静默、报告落 NDJSON 日志、DRY_RUN 同为源码硬编码。
5.3 expire-channels.js(到期文档任务触发)
扫描设置过过期时间的文档并把到期处理任务写入任务队列(taskPath),由服务端任务系统执行。实测(无到期文档):
cd /opt/cryptpad && node scripts/expire-channels.js
echo "exit=$?"
exit=0
静默完成,退出码 0。
5.4 restore-archived.js(归档恢复)
无参数、全量执行:遍历 data/archive 并把全部归档数据恢复回原位置,恢复动作逐条记入 NDJSON 日志(源码实测:无任何 CLI 参数解析,恢复的是整个归档区)。适合「误删后整体回滚」场景;只想恢复单个文档时,可直接把 data/archive/<目录>/<文件> 手工移回原目录。实测在空归档区执行正常退出。
5.5 user-statistics.js(用户用量统计 CSV)
遍历 pin 记录与 blob 存储统计每个用户的用量,输出 CSV。实测关键行为:
cd /opt/cryptpad/scripts && node user-statistics.js
["INFO","2026-10-21T21:17:33.998Z","QUOTA_UPDATED",{}]
["INFO","2026-10-21T21:17:33.999Z","START_LOADING_PINS",null]
["INFO","2026-10-21T21:17:34.000Z","ALL_PINS_LOADED",6]
CSV available at ../2026-10-21-stats.csv
输出路径为源码硬编码的 ../<当日日期>-stats.csv——相对当前工作目录的上一级,因此必须在 scripts/ 子目录里执行,产物才落在安装目录根(实测生成 /opt/cryptpad/2026-10-21-stats.csv)。CSV 表头实测原值:
"User key","Premium plan","Bytes","Number pads","Number blobs","First activity","Last activity","May be a team"
⚠️ 注意:若运行用户对上一级目录无写权限,实测报 [Error: EACCES: permission denied, open '../2026-10-21-stats.csv'] 后终止——安装根目录属主不是实例运行用户时即复现此错。
5.6 check-account-deletion.js(账户删除核查)
核查指定账户的 pin 记录与关联数据,两种用法(源码实测):
node scripts/check-account-deletion.js --ed <账户ed25519公钥>
node scripts/check-account-deletion.js --data '<含 toSign 与 proof 的签名字段 JSON>'
--ed 形态无需签名、直接按公钥核查;--data 形态要求提供账户签名过的删除请求(服务端验证签名后执行)。实测用一个随机生成的不存在账户公钥执行:
node scripts/check-account-deletion.js --ed "V6JqNZh7MwQ4CpBQJa-rnUKB6gAIA2o1Rip7Rp5b84A="
/cryptpad/scripts/check-account-deletion.js:43
if (err) { throw err; }
^
[Error: ENOENT: no such file or directory, open 'data/pins/b+/b+Sa+JOUonlhm+4rLIwv5zEn1ehiYnUMhqjzRQWGE4E=.ndjson'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'data/pins/b+/b+Sa+JOUonlhm+4rLIwv5zEn1ehiYnUMhqjzRQWGE4E=.ndjson'
}
即:2026.5.1 的该脚本对从未产生 pin 记录的账户直接抛 ENOENT(不报「账户不存在」而是当异常终止)。它面向的场景是「已知账户有 pin 数据、核查删除是否残留」,传不存在的账户公钥得到的就是上述报错——遇到时先确认公钥对应的账户确有数据。
5.7 clear.js(全库清空,危险)
删除实例全部数据,带交互确认。实测(回答 n 拒绝):
cd /opt/cryptpad && echo n | node scripts/clear.js
This will permanently delete all existing data on your instance. Are you sure (y/n)? Abort
确认词为 y 才执行,其余输入一律 Abort。生产环境严禁在未备份时执行;测试环境重建可用。
六、管理与诊断脚本
6.1 generate-admin-keys.js(支持邮箱密钥对生成)
为管理面板的「支持工单加密邮箱」生成专用密钥对。实测输出(私钥属敏感凭据,本文隐去取值):
cd /opt/cryptpad && node scripts/generate-admin-keys.js
You've just generated a new key pair for your support mailbox.
The public key should first be added to your config.js file ('supportMailboxPublicKey'), then save and restart the server.
Once restarted, administrators (specified with 'adminKeys' in config.js too) will be able to add the private key into their account. This can be done using the administration panel.
You will have to send the private key to each administrator manually so that they can add it to their account.
WARNING: the public and private keys must come from the same key pair to have a working encrypted support mailbox.
NOTE: You can change the key pair at any time if you want to revoke access to the support mailbox. You just have to generate a new key pair using this file, and replace the value in config.js, and then send the new private key to the administrators of your choice.
Your public key (add it to config.js):
CLsO9ZqJO4cakusqqs3PGTHXlO+8/1B/By/C0jiydl8=
Your private key (store it in a safe place and send it to your instance's admins):
<64 字符 Base64 私钥串,生成时一次性显示,需离线保存>
用法闭环:公钥写入 config.js 的 supportMailboxPublicKey → 重启 → 管理员(adminKeys 白名单内)在管理面板录入私钥启用加密工单箱;换钥即重跑本脚本并更新配置。
6.2 install.js(安装令牌生成,2026.5.1 已知缺陷)
npm 入口名 installtoken,用于重新生成 /install/#<令牌> 首次管理员注册链接的令牌。实测在 2026.5.1 官方发布包内报错:
Error: Cannot find module '../www/common/common-hash'
Require stack:
- /cryptpad/scripts/install.js
原因:脚本依赖的 www/common/common-hash.js 属于组件安装步骤(npm run install:components)产物,官方预构建发布形态未包含该文件。规避方法:服务启动日志本身会打印含令牌的注册链接(见部署指南篇 4.4 与本章 Q&A),日常不需要单独跑该脚本;确需在源码安装环境使用时先补齐组件再执行。
6.3 pinned.js(钉存明细统计,2026.5.1 已知缺陷)
按设计遍历 pin 记录输出各账户钉住明细。实测在本版本直接报错:
Error: Cannot find module '../lib/once'
Require stack:
- /cryptpad/scripts/pinned.js
lib/once 模块在 2026.5.1 代码树中不存在(上游缺陷)。用量统计请改用 5.5 的 user-statistics.js(实测可用)。
6.4 testcrypto.js(加密自检,2026.5.1 已知缺陷)
按设计对 tweetnacl/libsodium 实现做一致性自检。实测在 2026.5.1 官方发布包内报错:
Error: Cannot find module 'sodium-native'
Require stack:
- /cryptpad/scripts/testcrypto.js:5:20
sodium-native 为可选原生依赖,官方预构建发布形态未内置。仅用于开发环境诊断加密库,生产排障无需此脚本。
6.5 diagnose-archive-conflicts.js(归档冲突诊断)
扫描归档区与主存储间的不一致(同名冲突等)并输出诊断报告。实测为长时扫描型脚本(无参数,数据量大时耗时数分钟量级),正常实例输出空冲突即可放心;本篇实测空实例快速通过、无冲突输出。
6.6 issue-jwt.js(JWT 调试签发)
源码头注释原文声明该脚本「strictly for debugging purposes」——手工构造已认证会话与 JWT 以验证服务端校验逻辑,开发者调试用,运维日常用不到,不展开。
七、定时任务编排建议
综合官方注释(5.2 节原文:归档清理「每天由 crontab 执行」)与 2026.5.1 行为,推荐 crontab(以实例运行用户身份,crontab -e):
# 每日 03:17 清理归档区(超过 archiveRetentionTime 的删除数据永久清除)
17 3 * * * cd /opt/cryptpad && node scripts/evict-archived.js >> /opt/cryptpad/data/logs/cron.log 2>&1
# 每日 03:47 触发到期文档处理任务
47 3 * * * cd /opt/cryptpad && node scripts/expire-channels.js >> /opt/cryptpad/data/logs/cron.log 2>&1
不活跃数据清理(evict-inactive.js)在 disableIntegratedEviction 保持默认 false 时由服务端内置周期执行,无需再加 crontab;仅当该参数设为 true(完全手动治理)时才加入:
# 仅当 config.js 设置 disableIntegratedEviction: true 时启用
27 3 * * 0 cd /opt/cryptpad && node scripts/evict-inactive.js >> /opt/cryptpad/data/logs/cron.log 2>&1
💡 说明:脚本静默设计(结果落 NDJSON 日志),cron 重定向只兜底报错;执行结果去
data/logs/<UTC日期>/目录看EVICT_INACTIVE_FINAL_REPORT等事件。
八、注意事项
- 执行目录必须为安装目录:脚本以相对路径加载
../lib、../config,换目录执行必然加载失败;user-statistics.js又必须在scripts/子目录内执行才能把 CSV 落到安装根(5.5 实测); - 治理类脚本先备份再执行:
clear.js全库清空、restore-archived.js全量恢复、evict-*真实删除(本版本 DRY_RUN 需改源码,5.1); - 三个脚本的 2026.5.1 已知缺陷(本章实测):
install.js缺common-hash组件、pinned.js缺lib/once模块、testcrypto.js缺sodium-native依赖——遇到同款报错属上游问题,不是部署错误; - 脚本与服务进程写同一数据目录,生产执行建议安排在低峰并接受「与服务端内置清理互斥」的保守策略(二选一治理,避免竞争)。
九、常见问题
Q1:DRY_RUN=1 node scripts/evict-inactive.js 为什么不生效?
2026.5.1 源码把 Env.DRY_RUN 硬编码为 false(scripts/evict-inactive.js 第 20 行),环境变量无效。试运行需临时把该行改为 true,跑完改回(实测结论,5.1)。
Q2:清理脚本跑完控制台什么都没打印,怎么知道结果?
结果在磁盘 NDJSON 日志:data/logs/<UTC日期>/ 下最新文件,检索 EVICT_INACTIVE_FINAL_REPORT(含 channels/blobs/accounts 各计数)。
Q3:user-statistics.js 报 EACCES 写不进 CSV?
输出路径硬编码为「当前目录上一级」,运行用户须对安装根目录有写权限;属主不一致时需以对应属主身份执行,或把输出引导到可写目录(5.5 实测)。
Q4:想恢复单个被删文档,必须跑 restore-archived.js 吗?
不必。该脚本无参数且全量恢复整个归档区;单文件直接从 data/archive/ 手工移回 datastore/ 对应路径即可(5.4)。
Q5:首次管理员的注册链接丢了怎么办?
重启实例即可在启动日志重新看到 /install/#<令牌> 链接(对服务日志 grep Create your first admin 文案);scripts/install.js 在 2026.5.1 发布包内不可用(6.2)。
十、参考链接
| 资料 | 链接 |
|---|---|
| 官方仓库 scripts 目录(2026.5.1) | https://github.com/cryptpad/cryptpad/tree/2026.5.1/scripts |
| 官方仓库 package.json | https://github.com/cryptpad/cryptpad/blob/2026.5.1/package.json |
| 官方管理员指南 | https://docs.cryptpad.org/en/admin_guide/installation.html |
| 本系列部署篇 | 《CryptPad 2026.5.1 Docker Compose 部署指南》 |
| 本系列配置篇 | 《CryptPad 2026.5.1 配置参数详解》 |
| 本系列认知篇 | 《CryptPad 介绍与选型指南》 |