工具推荐·阅读约 2 分钟·
Bookshelf:零数据库的自托管电子书库,一个文件夹 + 对象存储就能跑

Bookshelf:零数据库的自托管电子书库,一个文件夹 + 对象存储就能跑

把 EPUB 和 PDF 丢进一个文件夹,Bookshelf 帮你发布成网页书库:Cloudflare Worker + R2 或本地 Node 服务器两条路线,无数据库,自带 OPDS 目录,Kobo 也能直接连。

原文来源:GitHub - murerkinn/bookshelf — 一个跑在对象存储上的自托管电子书库:无数据库、支持 Cloudflare R2 和本地目录两种存储、自带 OPDS 目录可连 Kobo。

买了不少电子书,想在自己设备上随时读,又不想把书都上传到别人的服务器——这是很多人的自托管入门需求。市面上的方案大多绕不开一个数据库:Calibre-web 要装 Calibre 全家桶,其他方案也要维护一个 SQLite 或者 Postgres。今天介绍的开源项目 Bookshelf 走了一条完全不同的路:它没有数据库,整个书库就是对象存储里的一堆静态文件。

Bookshelf 是什么

Bookshelf 是一个自托管电子书库,定位非常克制:把你已经拥有的 EPUB 和 PDF 放进一个文件夹,发布出去,就能在任何浏览器里阅读,或者通过 OPDS 目录在 Kobo 上直接浏览。项目主页的原话是:"为你已经拥有的电子书做一个自托管书库。"

两条运行路线,同一份代码:

  • Cloudflare Worker + R2:书库跑在 Cloudflare 的边缘网络上,无服务器架构
  • Node 服务器 + 本地目录:跑在自己机器或 VPS 上,纯文件系统存储

两种方式共用同一套同步工具和同一个书库格式,切换存储后端只需要改一行配置。

—— 广告 ——

为什么值得关注:架构上的巧思

Bookshelf 的"无数据库"不是偷懒,而是刻意设计。它的核心是一个叫 sync 的发布工具:你把书丢进 books/ 文件夹,运行 npm run sync,它会构建整个书库——生成封面、建立索引、产出 OPDS 目录——然后把结果以静态对象的形式发布到存储后端(R2 或本地目录)。

这个设计的直接好处是:

  1. 部署成本极低。Cloudflare Worker 免费额度内跑一个静态读取服务,存储用 R2,个人书库基本处于"一分钱不花"的区间。没有数据库要维护,没有实例要盯。
  2. 读取路径极简。Worker 只做一件事:按对象键返回内容。阅读位置(读到第几页)存在浏览器本地,服务端完全无状态。
  3. 存储层是可插拔的。项目把存储抽象成 provider,官方实现了 R2 和文件系统两种,第三方也可以发布自己的 provider 包,在配置里指名就能用。

对独立开发者来说,这是一个很好的"无服务器 + 无数据库"参考实现:一个服务能拆成"构建期"和"读取期",构建期干重活,读取期保持无状态——这种模式在个人工具类项目里非常实用。

怎么跑起来:三条路线

快速体验(Node 24+,Unix 系统):

code
git clone https://github.com/murerkinn/bookshelf.git
cd bookshelf
npm install
npm run demo

npm run demo 会生成 9 本公版书(8 本 EPUB + 1 本 PDF)写进 books/,不下载任何东西,一分钟内能看到效果。

本地文件系统:把配置里的存储 provider 改成 fs,指向一个目录:

code
{
  "storage": {
    "provider": "fs",
    "directory": "shelf-data"
  }
}

然后 npm run sync -- --create 构建书库,npm run build && npm start -w @bookshelf/app 启动服务,书库就在 http://localhost:3000

Docker(最短路径,镜像自带生成封面的工具):

code
mkdir books && cp ~/Downloads/*.epub books/
docker compose run --rm sync --create
docker compose up -d

Cloudflare(全球访问,无需自建服务器):

code
npx wrangler login
npm run sync -- --create
npm run deploy

需要注意 bookshelf.config.jsonwrangler.jsonc 里的桶名、Worker 名必须一致,不一致的话同步工具会在上传前停下。

必须知道的限制

Bookshelf 的 README 把限制写得很直白,这一点值得赞赏:

  • 没有认证。任何能访问到你书库的人,都能下载里面的每一本书,还能切换任意阅读档案(profile)。OPDS 目录是机器可枚举的,等于把你的书单暴露给了能访问的人。官方建议:放在你信任的网络里,或者前面套一层访问控制。
  • 不加密。书库明文存储,对象键是书名转化来的 slug——也就是说,列一下存储桶就能知道你的书架上有哪些书。
  • 双设备同时读同一个档案是 last-write-wins:A 设备读到第 50 页、B 设备读到第 20 页,后写入的会覆盖先写入的。多设备同步阅读进度不在设计目标内。
  • Windows 不支持——同步工具依赖 Unix 的 which 查找图片工具。
  • 提供 BOOKSHELF_READ_ONLY=1 环境变量,设置后存储只读,档案不能增删改,阅读位置只留在浏览器里。官方建议:凡是陌生人能访问到的部署,都设上这个。

适合谁用

适合:想把自己收藏的电子书搬上自己控制的服务、有 Cloudflare 账号或一台小 VPS、用 Kobo 或支持 OPDS 的阅读器的人。部署一次之后基本零维护,这是它最大的卖点。

不适合:需要多用户、多设备同步阅读进度、家庭共享场景的人——没有认证这一条就基本把多人共用的路堵死了。这种情况还是老老实实看 Calibre-web 或者商业服务。

说点看法

Bookshelf 是那种"小而正确"的项目:不做认证、不做同步,把"自己看书"这一个场景做到极致,剩下的边界写得清清楚楚。对独立开发者,它有两层参考价值——一层是工具本身(自托管书库确实好用),另一层是架构思路:当你只需要"个人使用"级别的服务时,无状态读取 + 构建期生成 + 对象存储,可能是比"服务器 + 数据库 + 认证体系"更聪明的默认选择。如果你的需求正好在它的边界内,这可能是你部署过最省心的自托管服务。

分享到
微博Twitter

© 2026 四月

原文链接:https://www.aprilzz.com/tools/bookshelf-self-hosted-ebook-library