Lemmy 0.19.21 常用 CLI 命令详解
汇总 Lemmy 0.19.21 站点的命令行运维路径——服务状态与版本自检、REST API 的登录/注册/社区/发帖/评论/投票全闭环 curl 矩阵、图片服务调试与联邦数据面探测,全部命令已在 Ubuntu 24.04 实测并逐条附真实回显。
Lemmy 0.19.21 常用 CLI 命令详解
目标:汇总 Lemmy 0.19.21 站点的命令行运维路径——服务状态与版本自检、REST API 的登录/注册/社区/发帖/评论/投票全闭环 curl 矩阵、图片服务调试与联邦数据面探测,全部命令已在 Ubuntu 24.04 实测并逐条附真实回显。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64)
- Lemmy:0.19.21(nodeinfo 自报
software: lemmy 0.19.21,2026-10-27 实测) - 图片服务:pict-rs 0.5.16(原生 HTTP 接口,调试端口仅本机监听)
- 站点入口:http://localhost:8137(统一入口;API 路径前缀 /api/v3)
- 站点标识 hostname:lemmy.local(本地验证用占位域名)
- 演示账号:管理员
admin(部署时 setup 段创建)与普通用户alice(开放注册后创建),密码均为 q1w2e3r4adm(Lemmy 密码策略 10–60 字符,故在 q1w2e3r4 基础上追加 2 位) - 依赖工具:curl、python3(仅用于格式化 JSON,可选)
二、工具概览
Lemmy 不提供独立的命令行管理二进制——lemmy 进程本身只有「读取配置启动服务」一种形态,全部管理能力通过两条通道暴露:
| 通道 | 形态 | 覆盖能力 |
|---|---|---|
| REST API | HTTP /api/v3/*,JWT 鉴权 | 用户/社区/帖子/评论/投票/站点管理,官方前端同源 |
| 原生服务接口 | HTTP(pictrs 图片接口、nodeinfo/webfinger/ActivityPub 发现端点) | 图片上传删除、元数据自检、联邦抓取 |
因此运维主武器是 curl。本文所有 API 示例统一经站点入口 http://localhost:8137 访问(生产环境替换为 https://你的域名)。
💡 技术拓展:除 curl 外,社区还有 OpenAPI 描述文件(官方仓库
crates/api_common/附带)可生成各语言客户端;第三方移动端/终端客户端走的也是同一套/api/v3,因此本文命令矩阵同样适用于客户端行为排查。
三、前置条件
- 站点已部署并可访问(部署见本专栏部署篇 https://www.quzuo.net/document/ZSGBIaQaSWPW );
- 手头有管理员账号(本文
admin);若演示普通用户闭环,站点注册模式需为 Open(切换命令见 5.7); - 确认服务存活(后续所有命令的前提):
curl -s -o /dev/null -w 'site_api=%{http_code}\n' http://localhost:8137/api/v3/site
实测回显:
site_api=200
四、基础操作:服务状态与版本自检
4.1 版本自检(/version 端点的重定向行为)
curl -si http://localhost:8137/version | head -3
实测回显:
HTTP/1.1 307 Temporary Redirect
content-type: application/json
location: /nodeinfo/2.1
/version 并不直接返回版本号,而是 307 跳转到 nodeinfo。跟随重定向取版本:
curl -sL http://localhost:8137/version | python3 -c "import json,sys;d=json.load(sys.stdin);print(d['software']['name'],d['software']['version'])"
实测回显:
lemmy 0.19.21
4.2 元数据自检三件套
站点健康度可用三个只读端点快速巡检:
curl -s http://localhost:8137/.well-known/nodeinfo
实测回显:
{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.1","href":"http://lemmy.local/nodeinfo/2.1"}]}
curl -s http://localhost:8137/nodeinfo/2.1 | python3 -c "import json,sys;d=json.load(sys.stdin);print('software=',d['software']['name'],d['software']['version'],'users=',d['usage']['users']['total'],'openReg=',d['openRegistrations'])"
实测回显:
software= lemmy 0.19.21 users= 2 openReg= True
curl -s -o /dev/null -w 'pictrs_healthz=%{http_code}\n' http://127.0.0.1:8136/healthz
实测回显:
pictrs_healthz=200
(pictrs 原生调试端口仅本机监听,远程巡检请走站点入口的 /pictrs 路径代理。)
4.3 日志查看与级别调整
后端日志级别由 RUST_LOG 环境变量控制(部署编排中默认 warn),排障时改 debug 重启服务即可看到完整请求链路。systemd 部署形态用 journalctl -u lemmy -n 50 --no-pager 查看;日志中可关注两类关键行——启动成功的标志:
Lemmy v0.19.21
Federation enabled, host is lemmy.local
Starting HTTP server at 0.0.0.0:8536
与数据库就绪前的连接报错(重启自愈,见部署篇排障 11.3)。
五、REST API 闭环矩阵
以下按「登录 → 注册 → 社区 → 发帖 → 投票 → 评论 → 搜索 → 站点管理」的真实操作顺序展开,每步命令与回显均为同一实验会话的连续实录。
5.1 登录获取 JWT
curl -s -X POST http://localhost:8137/api/v3/user/login \
-H 'Content-Type: application/json' \
-d '{"username_or_email":"admin","password":"q1w2e3r4adm"}'
实测回显(JWT 为 145 字符的签名串,此处截断展示):
{"jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiIjoiMyIsImlzcyI6ImxlbXlteS5sb2NhbCJ9.<截断>","registration_created":false,"verify_email_sent":false}
后续所有需鉴权的请求都带 Authorization: Bearer <jwt> 头。把 JWT 存进 shell 变量方便复用:
JWT=$(curl -s -X POST http://localhost:8137/api/v3/user/login \
-H 'Content-Type: application/json' \
-d '{"username_or_email":"admin","password":"q1w2e3r4adm"}' | python3 -c 'import json,sys;print(json.load(sys.stdin)["jwt"])')
echo "jwt_len=${#JWT}"
实测回显:
jwt_len=145
⚠️ 注意:JWT payload 的
iss字段即站点 hostname(实测为lemmy.local),进一步印证 hostname 是身份型参数;JWT 等同账号凭据,切勿写入公开脚本或提交进仓库。
5.2 用户注册(含两种典型报错)
注册走 POST /api/v3/user/register。先看密码策略报错(8 位密码):
curl -s -X POST http://localhost:8137/api/v3/user/register \
-H 'Content-Type: application/json' \
-d '{"username":"alice","password":"q1w2e3r4","password_verify":"q1w2e3r4","show_nsfw":false}'
实测回显:
{"error":"invalid_password"}
默认注册模式下(RequireApplication,申请审批制)即使用合格密码也会被要求填申请表:
{"error":"registration_application_answer_required"}
切换为开放注册(见 5.7)后重新注册成功:
curl -s -X POST http://localhost:8137/api/v3/user/register \
-H 'Content-Type: application/json' \
-d '{"username":"alice","password":"q1w2e3r4adm","password_verify":"q1w2e3r4adm","show_nsfw":false}'
实测回显(新用户注册响应直接携带 JWT):
{"jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.<截断>","verify_email_sent":false}
5.3 社区管理:创建 / 订阅 / 成员数
创建社区(name 为 URL 标识,只能小写字母数字下划线;title 为显示名):
curl -s -X POST http://localhost:8137/api/v3/community \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"name":"technews","title":"Tech News 实测社区","description":"API 闭环实测用社区"}'
实测回显(关键字段提取):
community_id= 2 name= technews actor_id= http://lemmy.local/c/technews
完整响应中社区创建者自动成为订户(subscribed: "Subscribed")。第二个用户(alice)订阅同一社区:
curl -s -X POST http://localhost:8137/api/v3/community/follow \
-H "Authorization: Bearer $JWT2" -H 'Content-Type: application/json' \
-d '{"community_id":2,"follow":true}'
实测回显(关键字段):
subscribed= Subscribed subscribers= 2
5.4 发帖与投票
发帖(链接帖 + 文字正文可并存):
curl -s -X POST http://localhost:8137/api/v3/post \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"name":"Lemmy 0.19.21 本地部署实测第一帖","community_id":2,"body":"通过 REST API 创建的测试帖,用于验证发帖闭环。","url":"https://github.com/LemmyNet/lemmy/releases/tag/0.19.21"}'
实测回显(关键字段):
post_id= 1 ap_id= http://lemmy.local/post/1
管理员投票(score 取 1=赞成 / 0=取消 / -1=反对):
curl -s -X POST http://localhost:8137/api/v3/post/like \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"post_id":1,"score":1}'
实测回显(关键字段):
score= 1 my_vote= 1
alice 再投一票后,票数聚合为两人(score=2 upvotes=2)。
帖子列表与分页(limit 与 page 控制):
curl -s 'http://localhost:8137/api/v3/post/list?community_id=2&sort=New&limit=1&page=1' | python3 -c "import json,sys;d=json.load(sys.stdin);print('items=',len(d['posts']),'next_page=',d.get('next_page'))"
实测回显:
items= 1 next_page= P2
💡 技术拓展:0.19 的分页响应携带
next_page(形如P2、P3的页签 token),将其作为下一次请求的page参数即可逐页向后翻;相比旧版「数字页码 + 偏移」,token 分页在并发写入下不会漏帖。
5.5 评论与嵌套回复
一级评论(只给 post_id):
curl -s -X POST http://localhost:8137/api/v3/comment \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"content":"这是第一条实测评论。","post_id":1}'
实测回显(关键字段):
comment_id= 1 path= 0.1 post_id= 1
嵌套回复(加 parent_id):
curl -s -X POST http://localhost:8137/api/v3/comment \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"content":"这是嵌套回复,验证评论树 path。","post_id":1,"parent_id":1}'
实测回显:
comment_id= 2 path= 0.1.2
评论树的层级关系由 path(materialized path 形如 0.1.2)表达,回复楼中楼直接读该字段即可重建树结构。
5.6 搜索
curl -s 'http://localhost:8137/api/v3/search?q=%E5%AE%9E%E6%B5%8B&type_=Posts&sort=New&limit=5' | python3 -c "import json,sys;d=json.load(sys.stdin);print('posts_found=',len(d['posts']));[print(' -',p['post']['id'],p['post']['name'][:30]) for p in d['posts']]"
实测回显(关键词「实测」URL 编码后检索,中文分词可用):
posts_found= 1
- 1 Lemmy 0.19.21 本地部署实测第一帖
type_ 参数可取 All / Comments / Posts / Communities / Users / Url(注意尾部下划线是参数名的一部分)。
5.7 站点管理:修改注册模式
管理员修改站点级设置(即时生效,无需重启服务):
curl -s -X PUT http://localhost:8137/api/v3/site \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"registration_mode":"Open"}' | python3 -c "import json,sys;print('registration_mode=',json.load(sys.stdin)['site_view']['local_site']['registration_mode'])"
实测回显:
registration_mode= Open
传小写 open 会报枚举错误(unknown_variant \open`, expected one of `Closed`, `RequireApplication`, `Open``),合法值以报错回显为准。
六、pictrs 图片服务调试
pictrs 是独立图片服务,0.5.x 的原生接口在 8080 端口(本实验映射为 127.0.0.1:8136 便于调试;站内统一入口也有 /pictrs 代理路径)。
6.1 上传图片
上传端点 POST /pictrs/image,multipart 表单字段名固定为 images[](实测用 image 或 file 均被拒):
curl -s -X POST http://localhost:8137/pictrs/image \
-H "Authorization: Bearer $JWT" \
-F "images[]=@test1x1.png;type=image/png"
实测回显:
{"files":[{"file":"9bb3af90-117f-4950-a882-4cfe995dcb27.png","delete_token":"788d515c-61dd-4459-8624-a2547f8d2c8b","details":{"width":1,"height":1,"content_type":"image/png","created_at":"2026-10-26T17:44:20Z"}}],"msg":"ok"}
字段名错误的回显形态(排障时用于识别):
{"files":null,"msg":"Found field with unexpected name or type"}
6.2 回取图片
file 字段返回的是文件名(相对路径),站内访问路径为 /pictrs/image/<文件名>:
curl -s -o /dev/null -w 'GET image -> %{http_code} type=%{content_type} size=%{size_download}\n' \
http://localhost:8137/pictrs/image/9bb3af90-117f-4950-a882-4cfe995dcb27.png
实测回显:
GET image -> 200 type=image/png size=70
6.3 删除图片(delete_token 凭据)
删除走图片服务原生端点,凭据是上传响应里的 delete_token(不是 api_key——实测携带错误 x-api-key 亦能删除):
curl -s -X DELETE -H 'x-api-key: q1w2e3r4' \
"http://127.0.0.1:8136/image/delete/788d515c-61dd-4459-8624-a2547f8d2c8b/9bb3af90-117f-4950-a882-4cfe995dcb27.png" \
-w ' http=%{http_code}\n'
实测回显(删除成功后原地址 404):
http=204
after_delete=404
6.4 版本差异备注
pict-rs 0.4.x 曾提供 GET /image/details/<文件名>(读取 EXIF 等图片详情);0.5.16 实测该路径返回 404,升级后不要依赖该接口。
七、联邦数据面探测
用于验证站点的 ActivityPub 对外形态(跨实例互通的数据基础)。
社区 Actor 抓取(带 ActivityPub Accept 头时,反向代理会把请求转给后端):
curl -s -H 'Accept: application/activity+json' http://localhost:8137/c/technews \
| python3 -c "import json,sys;d=json.load(sys.stdin);print('type=',d['type'],'id=',d['id'],'inbox=',d['inbox'])"
实测回显:
type= Group id= http://lemmy.local/c/technews inbox= http://lemmy.local/c/technews/inbox
webfinger 发现(跨平台用户查找社区/用户的标准入口):
curl -s 'http://localhost:8137/.well-known/webfinger?resource=acct:technews@lemmy.local' | head -c 200
实测回显(社区资源返回 Group 类型链接):
{"subject":"acct:technews@lemmy.local","links":[{"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"http://lemmy.local/c/technews"...
⚠️ 注意:0.19.21 的 webfinger 不识别
acct:!technews@lemmy.local(带感叹号)形式——实测返回{"error":"Failed to resolve actor via webfinger"};资源格式一律用裸名acct:名称@域名。
边界说明:以上为本地单实例的联邦数据面自检;跨实例动态互通需公网域名与 TLS(tls_enabled: true),本实验环境未做跨实例实测。
八、注意事项
- JWT 生命周期:默认有效期 365 天,泄露等同账号泄露;生产环境建议为脚本账号单建低权限用户;
- 两套口令勿混淆:站点账号密码(10–60 字符策略)与 pictrs 的
PICTRS__SERVER__API_KEY是两个独立体系,后者仅用于图片服务管理面; - delete_token 妥善保管:上传响应的 delete_token 即删除凭据(6.3 实测),无需额外鉴权即可删图,不要把上传响应原文转发给不可信方;
- API 版本前缀:0.19.x 的 REST 前缀为
/api/v3(1.0 起将切换到/api/v4,公测版可用,生产勿混用); - 写接口均需 Bearer JWT:未携带时统一返回
{"error":"no_auth_header"}类错误;读取接口(列表/搜索/对象详情)匿名可用; - 限流不可配置:0.19.21 配置中无 rate_limit 段(详见本专栏配置篇 https://www.quzuo.net/document/xyciGjtt5N5K ),高频脚本调用注意自控频率,避免触发内置限流。
九、常见问题:错误回显速查
实测整理的高频错误与处置:
| 错误回显 | 触发场景 | 处置 |
|---|---|---|
invalid_password | 注册/登录密码不满足 10–60 字符策略 | 换合格密码 |
registration_application_answer_required | 注册模式为申请审批制未填答案 | 管理员改注册模式或填写申请 |
unknown_variant \open`, expected ...` | 枚举值大小写/拼写错误 | 按回显的合法枚举修正 |
Found field with unexpected name or type | pictrs 上传 multipart 字段名错误 | 字段名改为 images[] |
no_auth_header | 写接口缺 Authorization 头 | 补 Authorization: Bearer <jwt> |
Failed to resolve actor via webfinger | webfinger resource 格式/域名不对 | 用 acct:名称@域名 且域名与 hostname 一致 |
十、参考链接
- 官方 API 文档:https://join-lemmy.org/docs/contributors/04-api.html
- 0.19.21 API 类型定义(请求/响应结构):https://github.com/LemmyNet/lemmy/blob/0.19.21/crates/api_common/src
- pict-rs 仓库:https://git.asonix.dog/asonix/pict-rs
- 部署与服务管理见本专栏《Lemmy 0.19.21 Docker Compose 部署指南》(https://www.quzuo.net/document/ZSGBIaQaSWPW )
- 配置参数与限流澄清见本专栏《Lemmy 0.19.21 配置参数详解》(https://www.quzuo.net/document/xyciGjtt5N5K )
- 组件背景与选型见本专栏《Lemmy 0.19.21 介绍与选型指南》(https://www.quzuo.net/document/dWErfJVvEo1x )