微光阅 Lumos Reader:把 NAS 书库带进随身阅读异世界

2315 字
12 分钟
微光阅 Lumos Reader:把 NAS 书库带进随身阅读异世界

有些人把 NAS 当作家庭服务器,有些人把它当作影音仓库,而我更愿意把它看成一座安静的私人图书馆。

问题在于:书可以安稳地躺在硬盘里,但阅读不应该被绑在 NAS 旁边。每次打开一本书,都先把整本文件搬到手机上,多少有点像为了看一页漫画,先把整套单行本扛回家。

所以我做了 微光阅 Lumos Reader:把书留在 NAS,把阅读带在身边。

它是一个面向个人书库的开源阅读系统。服务端负责守着文件,Web 和 Android 客户端负责浏览与阅读;正文、封面、漫画页和字体都按需读取,读到哪一页,就取哪一点内容。

微光阅 Lumos Reader 书库预览
微光阅 Lumos Reader 书库预览

项目地址:github.com/Alumos/LumosReader

Alumos
/
LumosReader
Waiting for api.github.com...
00K
0K
0K
Waiting...

它解决的到底是什么问题?#

如果你的书都在 NAS 上,那么通常会遇到几个很现实的问题:

  • 手机端想看书,却不想先下载整个 EPUB、PDF 或 CBZ。
  • 在 Web 和 Android 之间切换时,希望阅读进度、收藏和标签能保持一致。
  • 小说、漫画、PDF 的阅读方式不同,不能用同一个简陋的文件列表糊弄过去。
  • 书库是自己的,最好就一直留在自己的设备上,不必把整套书交给第三方云服务。

Lumos Reader 的目标并不是做一个“什么都能打开一点”的文件浏览器,而是把 NAS 变成一个真正可以长期使用的私人书库:服务端管理内容和状态,客户端只负责把阅读体验做好。

一句话看懂整体架构#

只读 NAS 书库
Go 服务端 ── SQLite:元数据 / 进度 / 收藏 / 标签 / 统计
├── Web:React + Vite + foliate-js / PDF.js
└── Android:Compose + Rust/UniFFI + 原生阅读组件

这个结构的核心思路很简单:书籍内容尽量只读,阅读状态单独保存;文件按需传输,客户端各自发挥。

这样做的好处是,NAS 上的书库可以保持稳定,服务端也不需要为了某个客户端去复制整套文件。Web 端和 Android 端共享同一个 API,进度、收藏、标签和阅读时长自然也就能同步。

服务端:安静地守着书库#

服务端使用 Go 编写,负责扫描书库、读取元数据、管理阅读状态,并向不同客户端提供统一 API。

目前支持的内容包括:

  • EPUB、MOBI、AZW3、PDF、CBZ/ZIP 和 TXT。
  • EPUB 标题、作者、系列、封面、固定版式和翻页方向等元数据。
  • 阅读位置、locator、最近阅读时间、累计阅读时长、收藏和标签。
  • 书架分类、搜索、字体上传与下载,以及近 30 日阅读统计。

这里比较重要的一点,是内容传输支持 HTTP Range,同时配合 ETagLast-Modified 和缓存策略。对于 PDF、漫画和大体积电子书来说,这比“打开时把整本文件读进内存”要实际得多。

漫画也有单独的处理路径:服务端可以先返回页面目录,客户端只请求当前页附近的图片,不需要提前把整个 CBZ 解压到磁盘。翻页时拿到下一页,体验就会更接近真正的阅读器,而不是在文件管理器里逐张点图片。

Web 端:书架、阅读器和搜索都在一个入口#

Web 客户端使用 React 和 Vite 构建,适合在电脑、平板以及手机浏览器中使用。

它包含一套完整的书库工作流:

  • 最近阅读、书架、分类树、格式筛选、标签筛选和只看收藏。
  • 网格与列表两种视图,方便在“看封面”和“快速扫描文件”之间切换。
  • 多卷漫画在网格视图中合并为系列卡片,列表视图中保留单卷信息。
  • 书籍详情页支持收藏和标签编辑,服务端返回的数据作为统一来源。
  • EPUB、MOBI、AZW3 使用 foliate-js,PDF 使用 PDF.js
  • 章节、卷册、字体和阅读设置都围绕阅读过程组织,而不是把功能堆在菜单里。

尤其是 PDF 和 CBZ 的读取策略,它们不会默认把整本内容一次性预取。对部署在家用 NAS 上的服务来说,这不仅能减少等待,也能降低带宽和内存压力。

Android 端:把书库装进口袋#

Android 客户端通过同一个服务端地址连接书库,不需要为移动端再维护一份孤岛数据。

客户端使用 Jetpack Compose 构建界面,并通过 Rust + UniFFI 处理网络、Cookie、Range 请求、元数据和进度队列。阅读位置会保存更细的 locator,因此 EPUB 章节、PDF 页面、漫画页和文本内容都能尽量准确地恢复到上次离开的地方。

此外,Android 端还准备了几类适合长时间阅读的能力:

  • 字体库与自定义字体。
  • 字号、阅读主题和翻页动画。
  • E-INK 黑白模式。
  • 图书与漫画分区浏览。
  • 收藏、标签和阅读统计同步。

简单说,NAS 负责“我有哪些书”,Android 负责“我现在读得舒不舒服”。两者各司其职,阅读体验才不会被基础设施拖后腿。

图书和漫画,不应该被一锅端#

Lumos Reader 对书籍类型的判断不是只看文件后缀,而是综合书架设置、文件格式、EPUB 固定版式和路径信息:

  1. 书架被显式指定为图书或漫画时,以设置为准。
  2. CBZZIP 默认视为漫画。
  3. 固定版式 EPUB 默认归入漫画类内容,但仍然使用 EPUB 阅读器渲染。
  4. 路径中包含“漫画”、mangacomicコミック 时,倾向于识别为漫画。
  5. 其他内容归入图书。

这里有一个容易被忽略的细节:分类信息和渲染器不是一回事。

一部固定版式 EPUB 可以被归到漫画书架,但真正打开时仍然走 EPUB 阅读器;客户端不会因为一个分类字段,就把所有内容粗暴地送进图片阅读器。看似只是一个判断顺序,实际却决定了书架是否会越用越乱。

推荐的目录结构如下:

/library/
├── 漫画/
│ └── 爱情/
│ └── 某个系列/
│ ├── 01.cbz
│ └── 02.cbz
└── 小说/
└── 爱情/
└── 某本小说.epub

当然,如果你的目录结构比较自由,也可以在 Web 或 Android 端为书架显式指定目录和内容类型。

在 NAS 上部署#

最推荐的方式是使用 Docker Compose。进入项目目录后,先准备环境文件:

Terminal window
cp .env.example .env

然后编辑 .env,至少修改管理员密码、书库目录和状态目录,再启动服务:

Terminal window
docker compose pull
docker compose up -d

默认服务只绑定到本机 127.0.0.1:8080。如果希望在 NAS 的其他端口访问,可以配置 PORT,然后通过反向代理提供 HTTPS。

部署时有几条建议值得认真对待:

  • 书籍目录尽量保持只读挂载。
  • .env、书籍内容和数据库不要提交到 Git。
  • 公网使用时务必配置 HTTPS,并设置真正的强密码。
  • 状态目录和字体目录单独备份。
  • 不要把整本书或包含隐私的日志上传到 Issue。

这个项目不包含任何书籍内容,书库的版权和访问权限需要由部署者自行确认。工具可以帮助我们更舒服地阅读,但它不会替我们解决内容授权问题。

给喜欢自己折腾的人#

如果你不想直接使用镜像,也可以本地开发。项目由 Go 服务端、React/Vite Web 端和 Android 客户端组成,分别位于:

cmd/lumosreader/ Go 程序入口
internal/server/ HTTP API、扫描器、EPUB 元数据、SQLite、运行时
web/ React/Vite 前端与嵌入资源
clients/android/ Compose 应用、Rust/UniFFI、native 阅读组件
scripts/ UI 与回归检查脚本
docs/ 预览图和开发设计记录

服务端最终可以把构建后的 Web 静态资源嵌入 Go 二进制,镜像运行时保持精简。对于 NAS 这类长期运行、希望少维护一点的设备来说,这种发布方式还是很舒服的。

写在最后:让阅读回到阅读本身#

我一直觉得,好的自托管软件不应该让人每天都在和它搏斗。

它应该像房间角落里的一盏灯:需要时一按就亮,不需要时安静地待在那里。Lumos Reader 想做的就是这种感觉——书库依然在自己的 NAS 里,数据不必被拆散到各个平台,换一台设备也能从上次停下的地方继续读。

如果说 NAS 是书库城堡,Lumos Reader 就是那条从城堡通往日常生活的传送门。电脑前可以读,沙发上可以读,出门后也可以继续读;而真正重要的那本书,始终还是稳稳地留在自己的书架上。

项目开源地址:Alumos/LumosReader

把书留在 NAS,把阅读带在身边。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
微光阅 Lumos Reader:把 NAS 书库带进随身阅读异世界
https://blog.alumos.cn/posts/lumos-reader/
作者
Alumos
发布于
2026-08-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Alumos
Hello, I'm Alumos.
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
最新动态
站点统计
文章
15
分类
4
标签
30
总字数
19,747
运行时长
0
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.15.4
文章许可
CC BY-NC-SA 4.0