Etherpad 3.3.9 常用 CLI 命令与工具详解

Etherpad 3.3.9 三类工具实测:启动参数、bin 运维脚本(插件装卸/pad 检查删除导出)与 HTTP API 1.3.1 全量端点(含 API 版本分级、错误码实测)。

EtherpadEtherpad协作编辑Node.js2026/10/22

Etherpad 3.3.9 常用 CLI 命令与工具详解

目标:系统梳理 Etherpad 3.3.9 的三类操作工具——服务启动命令行参数、内置 bin/ 运维脚本(插件管理、pad 检查/删除/导出)与 HTTP API——并逐条实测给出真实回显,全部命令已在 Ubuntu 22.04 实测通过(2026-10-22,Etherpad 3.3.9 + PostgreSQL 15,部署形态见《Etherpad 3.3.9 Docker Compose 部署指南》)。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64)
  • Etherpad:3.3.9(官方 Docker 镜像部署,安装路径 /opt/etherpad-lite,工作目录 /opt/etherpad)
  • 数据库:PostgreSQL 15(etherpad 库,store 单表 KV 存储)
  • API key:fKQy4G837VScLPnBeDTogEbl0fj41grIpmt6f9qsY(测试实例,配置方式见部署指南 4.3 节)
  • 服务端口:8134(映射服务内 9001),服务内认证模式 AUTHENTICATION_METHOD=apikey

二、工具概览

Etherpad 3.3.9 的运维操作分三类,作用面各不相同:

工具类别入口典型用途
服务启动命令行run.sh / node node/server.ts + 启动参数指定自定义 settings/credentials/sessionkey/APIKEY 文件启动
bin/ 运维脚本/opt/etherpad-lite/bin/*.ts(约 20 个,node + tsx 运行)插件装卸、pad 检查/删除/导出/压缩、数据库迁移
HTTP APIhttp://<host>:8134/api/<版本>/<函数>程序化建/读/写/删 pad、聊天、作者、统计

💡 说明:bin 脚本依赖 tsx 加载器,统一在安装目录的 src 子目录下以 node --require tsx/cjs ../bin/<脚本>.ts 方式运行——直接在根目录执行会报 Cannot find module 'tsx/cjs'(tsx 安装在 src/node_modules 下)。以运行服务的账号(如 etherpad)身份执行即可。

三、前置条件

# 确认服务在跑、API key 可读
curl -s http://127.0.0.1:8134/health
cat /opt/etherpad/data/APIKEY.txt

实测输出:

{"status":"pass","releaseId":"3.3.9"}
fKQy4G837VScLPnBeDTogEbl0fj41grIpmt6f9qsY

四、服务启动命令行参数

启动参数由服务端 src/node/utils/Cli.ts 解析,共 4 个文件位置覆盖参数(源码实测确认,无 --help 输出——传 --help 时按正常流程启动服务):

参数简写作用
--settings <路径>-s覆盖默认 settings.json 位置
--credentials <路径>无覆盖 credentials.json 位置(数据库凭据独立文件)
--sessionkey <路径>无覆盖会话密钥文件位置
--apikey <路径>无覆盖 APIKEY.txt 位置

实测验证 --apikey 参数生效(用自定义路径的 key 文件启动):启动日志出现 Api key file read from: "<自定义路径>" 即生效;文件不存在时服务端自动生成随机 key 并写出到该路径(源码行为:Api key file "..." not found. Creating with random contents.)。

源码包部署用 bin/run.sh 启动。run.sh 内置 root 拦截:以 root 运行时要求交互确认,实测输出:

You shouldn't start Etherpad as root!
Please type 'Etherpad rocks my socks' (or restart with the '--root'
argument) if you still want to start it as root:

按提示输入 Etherpad rocks my socks(或追加 --root 参数)即放行。生产建议以专用低权限账号(如 etherpad)运行。

五、bin 运维工具详解

5.1 plugins.ts —— 插件管理

子命令三件套:ls/list(列出)、install/i(安装,支持 --github、--path 指定来源)、rm/remove(卸载)。先查当前插件清单:

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/plugins.ts ls

实测输出(节选):

[2026-10-21T17:29:36.711] [INFO] settings - Installed plugins are: ep_etherpad-lite
[2026-10-21T17:29:36.721] [INFO] plugins - pnpm --version: 12.4.2

安装 ep_comments_page(评论侧栏插件):

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/plugins.ts install ep_comments_page

实测输出(节选):

[INFO] plugins - check installed plugins for migration
[INFO] settings - Installing plugin from registry: ep_comments_page
[INFO] plugins - pnpm --version: 12.4.2

验证安装结果与落盘:

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/plugins.ts ls
cat /opt/etherpad-lite/var/installed_plugins.json

实测输出:

[INFO] settings - Installed plugins are: ep_plugin_helpers, ep_comments_page, ep_etherpad-lite
{"plugins":[{"name":"ep_plugin_helpers","version":"0.6.9"},{"name":"ep_comments_page","version":"11.1.31"},{"name":"ep_etherpad-lite","version":"3.3.9"}]}

要点:依赖插件(ep_plugin_helpers)自动随装;插件实体落到插件目录(src/plugin_packages),清单落 var/installed_plugins.json;安装后需重启服务加载新插件。

卸载:

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/plugins.ts rm ep_comments_page

实测输出(节选):

[INFO] settings - Uninstalling plugin: ep_comments_page

⚠️ 排障实录:服务器直连 npm registry 失败时报 Error: Failed to get package 'ep_headerview' Response error 404 Not Found(经代理后 404 为插件真实不存在;直连超时则表现为连接错误)。出口受限的服务器先给执行环境注入代理再安装:export http_proxy=http://<代理IP>:<端口> https_proxy=同值。插件名以官方插件索引(https://static.etherpad.org/index.html)为准。

5.2 checkPad.ts / checkAllPads.ts —— pad 完整性检查

检查单个 pad 的修订链完整性:

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/checkPad.ts persist-test

实测输出(节选):

[INFO] settings - Checking if persist-test exists
[INFO] settings - Finished checking pad.

全库扫描(逐 pad 报 OK/损坏):

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/checkAllPads.ts

实测输出(节选):

[INFO] settings - Pad persist-test: OK
[INFO] settings - Finished.

5.3 deletePad.ts —— 删除单个 pad

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/deletePad.ts mixedcase99

实测输出:

Deleted pad { code: 0, message: 'ok', data: null }

⚠️ 排障实录:首次执行报 Error: ENOENT: no such file or directory, open '/opt/etherpad-lite/settings.json.docker'——该脚本族(deletePad/extractPadData 等)通过测试工具链 src/tests/container/loadSettings.js 读取 settings.json.docker。解决:cp /opt/etherpad-lite/settings.json /opt/etherpad-lite/settings.json.docker 后重跑即成功。此文件属一次性排障产物,无需持久化。

5.4 extractPadData.ts —— 导出 pad 全量数据

把一个 pad 的正文、修订、作者等全部数据库键导出为 dirty 格式 .db 文件(用于跨环境复现问题或单 pad 迁移):

cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/extractPadData.ts persist-test

实测输出(节选收尾):

[INFO] settings - finished

输出文件生成在执行时的工作目录(src)下:

ls -la /opt/etherpad-lite/src/persist-test.db

实测输出:

-rw-r--r--    1 etherpad root         890 Oct 21 17:31 /opt/etherpad-lite/src/persist-test.db

⚠️ 排障实录:该脚本依赖 dirty 模块(dirty 格式数据库驱动),Docker 官方镜像未预装,首次运行报 Error: Cannot find module 'dirty'。解决:cd /opt/etherpad-lite/bin && pnpm add dirty(注意装到 bin 目录而非 src——脚本在 bin/ 下,Node 模块解析止步于 bin/node_modules;装到 src 无效,本机实测验证)。

5.5 其余 bin 工具速查

同一运行方式(cd src && node --require tsx/cjs ../bin/<脚本>.ts),按用途归类:

脚本用途
compactPad.ts / compactAllPads.ts / compactStalePads.ts压缩修订历史,回收存储空间(单 pad/全库/陈旧 pad)
rebuildPad.ts / repairPad.ts从 changeset 重建 pad 正文 / 修复损坏 pad
migrateDB.ts / migrateDirtyDBtoRealDB.ts数据库间迁移(含 DirtyDB 迁正式库)
importSqlFile.ts导入 SQL 文件
createUserSession.ts为指定作者创建登录会话(配合访问控制)
deleteAllGroupSessions.ts清空分组会话
checkPad.ts 系列见 5.2

六、HTTP API 实测主线

6.1 认证方式

  • API key 模式(AUTHENTICATION_METHOD=apikey):请求带 apikey 参数即可,官方同时接受 api_key、authorization 三个参数名(任选其一,源码实测确认);
  • sso 模式(默认):不启用 APIKEY.txt,HTTP API 走 OIDC 令牌;curl 直调报错实测:
curl -s "http://127.0.0.1:8134/api/1/createPad?padID=demo1"

实测输出:

{"code":4,"message":"no or wrong API Key","data":null}

key 错误同理返回 code 4。key 校验为常数时间比较(防时序攻击,源码注释确认)。

6.2 API 版本与函数分级(关键实测发现)

API 版本查询:

curl -s http://127.0.0.1:8134/api

实测输出:

{"currentVersion":"1.3.1"}

URL 中的版本号决定可用函数集:/api/1/ 只有 v1 基础函数;/api/1.3.1/ 才有全量函数。实测对照(同一函数不同版本路径):

curl -s "http://127.0.0.1:8134/api/1/listAllPads?apikey=$KEY"
curl -s "http://127.0.0.1:8134/api/1.3.1/listAllPads?apikey=$KEY"

实测输出:

{"code":3,"message":"no such function","data":null}
{"code":0,"message":"ok","data":{"padIDs":["apidemo","persist-test"]}}

排障提示:遇到 {"code":3,"message":"no such function"} 先检查 URL 版本路径,再怀疑函数不存在。

6.3 pad 生命周期端点(创建/读写/版本)

KEY=$(cat /opt/etherpad/data/APIKEY.txt)
B="http://127.0.0.1:8134/api/1.3.1"

创建 pad(返回一次性删除令牌 deletionToken,用于无账号删除 pad):

curl -s "$B/createPad?apikey=$KEY&padID=apidemo&text=hello%20api"

实测输出:

{"code":0,"message":"ok","data":{"deletionToken":"31689af77cb42957cd5e5c28b88145798fd2c347e9f6b7fdd8ac344f74d92a3c"}}

重复创建同名 pad 返回 code 1:

{"code":1,"message":"padID does already exist","data":null}

写文本(POST 表单):

curl -s -X POST "$B/setText?apikey=$KEY&padID=apidemo" -d 'text=line1%0Aline2%0Aline3'

实测输出:

{"code":0,"message":"ok","data":null}

读文本:

curl -s "$B/getText?apikey=$KEY&padID=apidemo"

实测输出:

{"code":0,"message":"ok","data":{"text":"line1\nline2\nline3\n"}}

读 HTML(富文本形态):

curl -s "$B/getHTML?apikey=$KEY&padID=apidemo"

实测输出:

{"code":0,"message":"ok","data":{"html":"<!DOCTYPE HTML><html><body>rev2 content<br></body></html>"}}

版本数与最后编辑时间:

curl -s "$B/getRevisionsCount?apikey=$KEY&padID=apidemo"
curl -s "$B/getLastEdited?apikey=$KEY&padID=apidemo"

实测输出:

{"code":0,"message":"ok","data":{"revisions":1}}
{"code":0,"message":"ok","data":{"lastEdited":1792603950370}}

只读 ID 与反查:

curl -s "$B/getReadOnlyID?apikey=$KEY&padID=apidemo"
curl -s "$B/getPadID?apikey=$KEY&roID=r.4800fb390418296b3ea1fe4fca6c4704"

实测输出:

{"code":0,"message":"ok","data":{"readOnlyID":"r.4800fb390418296b3ea1fe4fca6c4704"}}
{"code":0,"message":"ok","data":{"padID":"apidemo"}}

6.4 聊天、作者与统计端点

# 追加聊天消息
curl -s -X POST "$B/appendChatMessage?apikey=$KEY&padID=apidemo" -d 'text=hello%20from%20api'
# 读聊天历史
curl -s "$B/getChatHistory?apikey=$KEY&padID=apidemo"
# 创建作者
curl -s -X POST "$B/createAuthor?apikey=$KEY" -d 'name=tester'
# 实例统计
curl -s "$B/getStats?apikey=$KEY"

实测输出:

{"code":0,"message":"ok","data":null}
{"code":0,"message":"ok","data":{"messages":[{"text":"hello from api","time":1792604006921,"userId":null,"userName":null}]}}
{"code":0,"message":"ok","data":{"authorID":"a.ooP4hVODnEX3BVXn"}}
{"code":0,"message":"ok","data":{"totalPads":2,"totalSessions":0,"totalActivePads":0}}

6.5 删除 pad 与错误码总表

curl -s "$B/deletePad?apikey=$KEY&padID=apidemo"

实测输出:

{"code":0,"message":"ok","data":null}

对不存在 pad 执行删除/读取返回 code 1(本机先用 bin 脚本删除 mixedcase99 后再用 API 删同一 pad 的实测):

{"code":1,"message":"padID does not exist","data":null}

错误码汇总(全部实测命中):

code含义实测触发方式
0成功正常调用
1业务错误(pad 不存在/已存在等)读/删不存在的 pad;重复 createPad
3函数不存在URL 版本路径下无此函数(如 /api/1/listAllPads)
4认证失败缺 apikey / key 错误 / sso 模式未带令牌

七、注意事项

  • bin 脚本统一 cd /opt/etherpad-lite/src 后执行(tsx 解析依赖 src/node_modules),并以运行服务的账号(如 etherpad)身份执行;
  • 插件装卸后需重启服务进程才能加载/卸载前端资源;
  • HTTP API 的写操作(setText/setHTML)会直接产生新修订,与网页编辑等效,注意与在线用户并发编辑的相互覆盖;
  • deletePad 不可逆;带 deletionToken 的无账号删除走 deletePad 端点时以 token 参数代替 apikey 身份;
  • API 逐函数参数表见官方文档 https://docs.etherpad.org/api.html(与 1.3.1 函数表一致,查询日期 2026-10-22)。

八、常见问题

Q1:bin 脚本报 Cannot find module 'tsx/cjs' 在错误目录执行导致。统一 cd /opt/etherpad-lite/src && node --require tsx/cjs ../bin/<脚本>.ts。

Q2:deletePad/extractPadData 报找不到 settings.json.docker 脚本族走测试配置加载器。cp settings.json settings.json.docker(在 /opt/etherpad-lite 下)后重跑(见 5.3 排障实录)。

Q3:extractPadData 报 Cannot find module 'dirty' 镜像未预装该模块。cd /opt/etherpad-lite/bin && pnpm add dirty(必须装在 bin 下,见 5.4 排障实录)。

Q4:插件安装 404 或连接失败 插件名以官方索引为准(404 即名字不存在,如 ep_headerview);连接失败先给执行环境配代理(见 5.1 排障实录)。

Q5:API 返回 no such function URL 版本路径低于函数引入版本。统一用 /api/1.3.1/(见 6.2 实测)。

九、参考链接

  1. 官方 HTTP API 文档:https://docs.etherpad.org/api.html (查询日期 2026-10-22)
  2. 官方插件索引:https://static.etherpad.org/index.html (查询日期 2026-10-22)
  3. bin 脚本源码目录:https://github.com/ether/etherpad/tree/HEAD/bin (查询日期 2026-10-22)
  4. 站内延伸:《Etherpad 介绍与选型指南》《Etherpad 3.3.9 Docker Compose 部署指南》《Etherpad 3.3.9 配置参数详解》