- 后端
- 社交
【免费下载链接】lemmy
🐀 A decentralised discussion platform for communities.
Lemmy 是一个面向联邦宇宙(Fediverse)的开源链接聚合器与论坛系统:任何人均可轻松自托管服务器,所有服务器通过 ActivityPub 协议相互联邦,如同电子邮件一般互联互通。本文以仓库内简体中文 README(readmes/README.zh.hans.md)为主线,结合仓库源码与配置文件,系统讲解 Lemmy 的架构组成、核心特性、配置参数与 Docker 部署流程,帮助你从零搭建并运维一个属于自己的联邦论坛实例。
从 Reddit 到联邦宇宙:Lemmy 的定位与核心理念
从产品形态上看,Lemmy 与 Reddit、Lobste.rs、Hacker News 等网站非常相似:你可以订阅感兴趣的论坛(社区)、发布链接与讨论帖、对内容投票和评论。然而在幕后,Lemmy 与它们有本质区别——任何人可以轻易运行一台服务器,而所有服务器都是联邦式的(可以类比电子邮件系统),并共同连接到同一个被称为联邦宇宙的网络。
对于一个链接聚合器而言,这种联邦架构意味着:在一台服务器上注册的用户,可以订阅任何其他服务器上的论坛,并与在其他服务器注册的用户展开讨论。这使得 Lemmy 成为 Reddit 及其他链接聚合器的一个易于自托管、分布式、不受单一公司控制与干涉的替代方案。
同时,每台 Lemmy 服务器都可以独立制定自己的管理政策:任命全站管理员和社区版主,用于阻止引战和钓鱼用户,营造健康、无毒、人人都能放心贡献的环境。这种"实例自治 + 跨实例互通"的设计,是理解 Lemmy 一切功能与配置的起点。
顺带一提,"Lemmy" 这个名字的由来颇为有趣:它既取自 Motörhead 乐队主唱的名字,也指向老牌电子游戏《Lemmings》、超级马里奥中的库巴(Lemmy Koopa),以及一种毛茸茸的啮齿动物旅鼠。
技术栈与源码架构
构建技术栈
根据 README 的"采用以下项目构建"一节,Lemmy 由以下技术构建:
- Rust:服务端主语言,保证高性能与内存安全;
- Actix:异步 Web 框架,承载 HTTP API 与 WebSocket 长连接;
- Diesel:类型安全的 ORM 与查询构建器,对接 PostgreSQL;
- Inferno:虚拟 DOM 渲染库(用于官方前端 lemmy-ui);
- TypeScript:前端开发语言。
在 Cargo.toml 中可以印证这一技术选型:工作区依赖中明确声明了actix-web(含 brotli/gzip/zstd 压缩、cookies、rustls 支持)、diesel(PostgreSQL、serde_json、uuid 等特性)、activitypub_federation(0.7.0-beta.11,含 actix-web 集成)、reqwest(HTTP 客户端)、tokio、extism(WebAssembly 插件加载)等关键依赖。当前仓库版本为1.0.0-beta.2,要求 Rust 版本不低于 1.92。
Cargo Workspace 的模块化组织
从仓库根目录的 Cargo.toml 可以看到,Lemmy 后端被拆分为数十个相互独立的 crate,形成清晰的分层架构:
- crates/api:HTTP API 层,进一步细分为
api(核心端点)、api_crud(增删改查)、api_common(公共类型)、api_utils(工具)、routes/routes_v3(路由注册); - crates/apub:ActivityPub 联邦层,包含
apub(核心协议实现,含 collections 集合、protocol 协议类型)、activities(各类联邦活动)、objects(ActivityPub 对象)、send(出站活动发送); - crates/db_schema:数据库表结构定义,由 Diesel 驱动;
- crates/db_views:数据库视图层,按业务域拆分,如
post、comment、community、modlog、notification、private_message、report_combined等二十余个模块; - crates/routes:非 API 的 HTTP 路由,如 RSS/Atom 订阅(
feeds)、图片(images)、nodeinfo、webfinger等,见 crates/routes/src/lib.rs; - crates/server:服务端入口,负责启动 HTTP 服务器、执行数据库迁移与定时任务;
- crates/utils:通用工具与全局设置(
settings)解析; - crates/email:邮件发送;
- crates/diesel_utils:Diesel 迁移与 schema 维护工具。
服务端入口与命令行参数
服务进程的入口在 crates/server/src/main.rs:它通过clap解析命令行参数(定义见 crates/server/src/lib.rs),并依据配置中的json_logging选项决定以 JSON 还是文本格式输出日志,然后调用start_lemmy_server启动。CmdArgs提供的核心启动参数包括:
| 参数 | 环境变量 | 说明 |
|---|---|---|
--disable-scheduled-tasks | LEMMY_DISABLE_SCHEDULED_TASKS | 不运行定时任务,多进程部署时建议只在其中一个进程关闭该选项 |
--disable-http-server | LEMMY_DISABLE_HTTP_SERVER | 关闭 HTTP 服务,仅运行定时任务或活动发送 |
--disable-activity-sending | LEMMY_DISABLE_ACTIVITY_SENDING | 禁用出站 ActivityPub 消息发送,用于水平扩展场景 |
--federate-process-index/--federate-process-count | LEMMY_FEDERATE_PROCESS_INDEX/LEMMY_FEDERATE_PROCESS_COUNT | 将联邦发送工作负载拆分到 n 个进程时,为每个进程分配索引 i(默认均为 1) |
migration run/migration revert | — | 执行待处理迁移的up.sql(最旧到最新),或回滚非待处理迁移的down.sql(最新到最旧) |
核心特性全景
README 列出了 Lemmy 的完整特性清单,下面结合仓库源码逐一展开说明。
自托管与易部署
Lemmy 是开源软件,采用 AGPL 协议(见仓库根目录 LICENSE),并随附Docker与Ansible两套部署方案。仓库中的 docker/docker-compose.yml 提供了一条完整可用的部署链路,后文"部署实战"一节将详细解读。
界面与交互体验
- 简洁、移动端友好的界面:注册只需用户名和密码即可完成;
- 用户头像支持;
- 实时更新的评论串:由 Actix 驱动的 WebSocket 通道推送新评论;
- 类似旧版 Reddit 的评分功能
(+/-):支持帖子与评论的点赞/点踩,对应源码中的like端点(见 crates/api/api/src/post/like.rs 等); - 主题系统:提供深色、浅色与 Solarized 主题;
- Emoji 与自动补全:输入
:触发候选; - 提及语法:用
@提及用户,用!提及社区; - 图片上传集成:帖子和评论中均可上传图片,后端由独立的 pictrs 图片服务承载;
- 帖子内容自由组合:一个帖子可以由标题与自我文本、URL 的任意组合构成,也可以两者皆无;
- 通知与私信:评论回复和被提及时推送通知,通知可经电子邮件发送,并支持站内私信(对应
private_message相关端点与 crates/db_views/private_message 视图模块); - i18n 国际化支持;
- RSS / Atom 订阅:覆盖
All、Subscribed、Inbox、User、Community五种信息流,路由实现在 crates/routes/src/feeds。
多重发布(Cross-posting)
在创建新帖子时,Lemmy 会提供相似帖子建议,这对问答式社区尤其有用,可有效避免重复发帖。
监管能力
Lemmy 为站点管理员与社区版主提供了完整的治理工具箱:
- 公开的修改日志(Moderation Logs):对应 crates/db_views/modlog 视图与 API 中的
mod_log端点; - 帖子置顶:可将帖子固定在社区顶部(
feature端点); - 双重治理体系:既有全站管理员(admin),也有社区版主,版主可以任命其他版主(
add_mod端点); - 锁定、删除与恢复帖子和评论(
lock、hide等端点); - 封禁与解禁:可针对社区或全站封禁用户(
ban、ban_person端点); - 转让:可以将网站和社区转让给其他人(
transfer端点)。
数据删除、NSFW 与性能
- 用户可以完全删除自己的数据,以替身(placeholders)替换所有帖子和评论;
- 支持NSFW 帖子 / 社区,并提供相应的可见性控制;
- 高性能:服务端采用 Rust 编写;按 README 记载,前端 gzip 后约
~80kB;支持arm64 架构与树莓派(Dockerfile 的构建参数CARGO_BUILD_FEATURES与RUST_RELEASE_MODE均可在交叉场景下调整)。
联邦机制:ActivityPub 与跨实例交互
联邦是 Lemmy 区别于传统论坛的核心能力。从源码结构看,联邦功能集中在 crates/apub 下:
- 协议层:
crates/apub/apub/src/protocol定义了 ActivityPub 协议类型; - 集合(Collections):crates/apub/apub/src/collections 实现了社区的关注者列表(
community_follower)、版主列表(community_moderators)、精选帖(community_featured)与 outbox(community_outbox)等联邦集合; - 对象与活动:
objects目录定义 Person、Community、Post、Comment 等 ActivityPub 对象,activities目录实现 Follow、Like、Create 等联邦活动; - 出站发送:
send目录负责将本地活动以签名请求发送至远端实例,发送并发数可由配置federation.concurrent_sends_per_instance控制。
在 api_tests/src/follow.spec.ts 中可以直观看到联邦关注的测试流程:本地用户关注社区后,subscribers与subscribers_local计数递增;跨实例关注时,远端实例(beta)上的社区会先进入pending状态,待接受(accepted)后follow_state变为accepted,随后退订(unfollow)操作同样会被联邦化传播。
为了验证联邦行为,仓库在 docker/federation/docker-compose.yml 中内置了一套五实例联邦测试环境:lemmy-alpha(8541 端口)、lemmy-beta(8551)、lemmy-gamma(8561)、lemmy-delta(8571,仅对 beta 开放白名单)与lemmy-epsilon(8581,配置了封禁 alpha 的黑名单),每台实例均配套独立的 lemmy-ui 与 PostgreSQL 数据库,可用于演练跨实例订阅、白名单/黑名单隔离等场景。
配置文件详解:从 defaults.hjson 到 Settings 结构体
Lemmy 使用 HJSON(带注释的 JSON 超集)作为配置格式。仓库中的 config/defaults.hjson 是完整的默认配置模板,对应源码中的Settings结构体定义(见 crates/utils/src/settings/structs.rs)。下面逐项说明:
database:数据库连接
database: { connection: "postgres://lemmy:password@localhost:5432/lemmy" pool_size: 30 }connection:指向 PostgreSQL 实例的连接 URI,也可通过环境变量LEMMY_DATABASE_URL覆盖;pool_size:最大活跃 SQL 连接数。需要留意的是,数值过高可能触发could not resize shared memory segment错误,此时需在 Docker 中调大共享内存(shm)大小。
pictrs:图片服务
pictrs: { url: "http://localhost:8080/" api_key: "string" }pictrs 是 Lemmy 配套的图片托管服务。url为其地址;api_key为自定义 API 密钥,删除图片时必需,因此在生产环境务必设置并妥善保管。
email:邮件通知
email: { connection: "smtps://user:pass@hostname:port" smtp_from_address: "noreply@example.com" }除 login/password 外的选项均为必填。connection遵循 lettre 的 SMTP URL 语法(如smtps://user:pass@hostname:port);smtp_from_address为发件人地址,例如noreply@your-instance.com。邮件用于回复通知、密码重置与注册验证等场景(对应 crates/email crate)。
setup:首次启动的自动初始化
setup: { admin_username: "admin" admin_password: "tf6HHDS4RolWfFhk4Rq9" site_name: "My Lemmy Instance" admin_email: "user@example.com" bootstrap_instances: [ "string" ] }这些参数仅在实例首次启动时生效,用于自动创建管理员账号与站点:admin_username为管理员用户名;admin_password长度须在 10~60 字符之间;site_name为站点名称(最长 20 字符,之后可在后台修改);admin_email可选,可留空后通过网页设置。bootstrap_instances用于在首次启动时从所列实例抓取最活跃的 50 个社区作为初始数据,按列表顺序依次尝试、失败则回退到下一个,置空可禁用社区引导。
网络与安全
hostname: "unset" # 实例域名(必填) bind: "0.0.0.0" # 监听地址 port: 8536 # 监听端口 tls_enabled: true # 是否启用 TLS,联邦必须为 true cors_origin: [ "lemmy.tld" ]hostname为实例对外域名,必须设置;tls_enabled控制站点是否通过 TLS 对外提供,联邦正常工作要求必须为true;cors_origin设置响应的Access-Control-Allow-Origin头,也可通过环境变量LEMMY_CORS_ORIGIN=example.org,site.com(逗号分隔)覆盖。
federation、prometheus 与 json_logging
federation: { concurrent_sends_per_instance: 1 } prometheus: { bind: "127.0.0.1" port: 10002 } json_logging: falsefederation.concurrent_sends_per_instance限制发往单个目标实例的并发出站联邦请求数;仅当实例规模很大(每秒超过约 10 条活动)且接收端跟不上时,才建议调高到 6 等数值。prometheus开启内置指标端点供监控抓取(默认仅监听回环地址)。json_logging为true时日志以 JSON 格式输出,方便接入日志采集系统;也可用环境变量NO_COLOR关闭日志的 ANSI 颜色。
plugins:WebAssembly 插件
plugins: [ { file: "https://.../go_replace_words.wasm" hash: "37cdc01a..." allowed_hosts: [ "lemmy.ml" ] config: { string: "string" } } ]Lemmy 支持通过Extism加载 WebAssembly 插件(依赖见 Cargo.toml)。每个插件条目包含:.wasm文件的本地路径或 URL(file)、文件 SHA256 哈希(hash,用于安全校验)、插件可访问的网站白名单(allowed_hosts)以及自定义配置(config)。
部署实战:Docker 方式从零起步
五服务架构
仓库根目录的 docker/docker-compose.yml 定义了完整的部署拓扑,共五个服务:
| 服务 | 镜像/来源 | 职责 |
|---|---|---|
proxy | nginx:1-alpine | 对外唯一入口,监听 1236/8536 端口,路由前端与后端流量 |
lemmy | 由 docker/Dockerfile 构建 | Lemmy 后端服务,加载 docker/lemmy.hjson 配置 |
lemmy-ui | dessalines/lemmy-ui:nightly | 官方网页前端,通过环境变量LEMMY_UI_BACKEND=lemmy:8536指向后端 |
pictrs | asonix/pictrs:0.5 | 图片托管服务,数据卷挂载到./volumes/pictrs |
postgres | pgautoupgrade/pgautoupgrade:18-alpine | PostgreSQL 数据库,端口映射5433:5432避免与宿主机冲突 |
其中lemmy服务通过LEMMY_DISABLE_ACTIVITY_SENDING=true与RUST_LOG环境变量控制行为与日志级别;数据库、pictrs 的凭据与地址均与 docker/lemmy.hjson 中的配置保持一致(如数据库连接postgres://lemmy:password@postgres:5432/lemmy、pictrs 密钥my-pictrs-key)。
nginx 反向代理与内容协商
docker/nginx.conf 揭示了 Lemmy 对外服务的流量分发逻辑,这是部署中最值得理解的部分:
- 两个 upstream 分别指向
lemmy:8536(后端)与lemmy-ui:1234(前端); - 对于
Accept头为application/activity+json或application/ld+json; profile="https://www.w3.org/ns/activitystreams"的请求(即联邦网络发来的 ActivityPub 请求),以及所有POST请求,一律转发给后端lemmy; - 其余普通浏览器请求转发给
lemmy-ui前端; location ~ ^/(api|pictrs|feeds|nodeinfo|version|.well-known)明确将 API、图片、RSS 订阅、NodeInfo、版本与 WebFinger(.well-known)路径直接代理到后端;- 同时启用了 gzip 压缩、20M 上传上限(
client_max_body_size 20M)以及X-Frame-Options、X-Content-Type-Options等安全响应头。
这种"按请求头内容协商分流"的设计,是 Lemmy 同时服务人类用户(HTML 前端)与联邦节点(ActivityPub JSON)的关键。
最小配置示例
仓库根目录的 config/config.hjson 给出了一个极简配置:
{ hostname: lemmy-alpha }正如注释所述,其余字段均可采用 config/defaults.hjson 的默认值;而 docker/lemmy.hjson 展示了开发环境下的完整实例配置,覆盖setup、database、hostname、bind、port、pictrs等关键项。注意 docker 目录内的配置仅用于 dev/main 分支,生产发布版本应参照官方配置文档编写。
生态项目与开发
围绕 Lemmy 核心服务,官方与社区还维护着一系列配套项目:lemmy-ui是 Lemmy 的官方网页应用(本文部署拓扑中的前端服务即来源于此);移动端方面有原生 Android 应用Jerboa(由 Lemmy 开发者打造)、原生 iOS 应用Remmel以及跨平台客户端Lemmur;API 客户端库包括lemmy-js-client(JavaScript/TypeScript)、Kotlin API client与Dart API client。
对于开发者而言,仓库提供了完整的测试与开发支撑:
- API 测试套件位于 api_tests,基于 Jest 编写,覆盖帖子、评论、社区、关注、私信、图片、用户等核心场景(如 api_tests/src/post.spec.ts、api_tests/src/follow.spec.ts);
- 联邦测试可通过 api_tests/run-federation-test.sh 与 api_tests/prepare-drone-federation-test.sh 配合五实例环境启动;
- 开发辅助脚本位于 scripts,包含
start_dev_db.sh(启动开发数据库)、lint.sh、test.sh、dump_schema.sh等常用工具。
结语
Lemmy 用 Rust 与 Actix 构建了高性能的后端,用 ActivityPub 实现了真正去中心化的跨实例互通,再以 Docker 与 Ansible 将自托管门槛降到最低——这正是它在联邦宇宙生态中成为 Reddit 类站点替代方案的核心竞争力。通过本文,你应该已经掌握了 Lemmy 的架构分层、联邦机制、全部核心配置参数以及 Docker 部署的关键细节;接下来可以直接基于 config/defaults.hjson 与 docker/docker-compose.yml 动手搭建自己的实例,并借助 docker/federation 下的多实例环境验证联邦行为。
- 后端
- 社交
【免费下载链接】lemmy
🐀 A decentralised discussion platform for communities.
相关推荐
Lemmy:联邦宇宙中的开源链接聚合平台
Lemmy:联邦宇宙中的开源链接聚合平台 Lemmy是一个基于ActivityPub协议的联邦式开源链接聚合平台,采用Rust语言构建后端服务,前端使用Type
后端社交Lemmy 项目全览:基于 Fediverse 的 Rust 联邦式链接聚合器与社区论坛
Lemmy 项目全览:基于 Fediverse 的 Rust 联邦式链接聚合器与社区论坛 导读 Lemmy 是一个面向 Fediverse(联邦宇宙)的开源链接
后端社交Angular-drag-and-drop-lists 完全指南:10分钟掌握HTML5原生拖拽排序
Angular drag and drop lists 完全指南:10分钟掌握HTML5原生拖拽排序 Angular drag and drop lists是一
UI库/组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考