Bookshelf, самостоятельно размещаемая библиотека книг для EPUB и PDF

Bookshelf, самостоятельно размещаемая библиотека книг для EPUB и PDF

На GitHub опубликован проект Bookshelf, самостоятельно размещаемая (self-hosted) библиотека для электронных книг, которыми пользователь уже владеет. Одна серверно-рендерённая страница показывает список книг, ищет по ним через строку поиска, отдаёт файлы на скачивание и открывает их прямо в браузере: у EPUB и PDF, по отдельной читалке для каждого формата.

Проект работает в двух режимах. Первый, как воркер Cloudflare (Cloudflare Worker) поверх объектного хранилища R2, без своего аккаунта пользователя: нужен только аккаунт Cloudflare и wrangler login. Второй, как обычный Node-сервер поверх директории на диске, без каких-либо внешних аккаунтов вообще: путь к папке задаётся в bookshelf.config.json. Библиотеку в обоих случаях собирает отдельный инструмент синхронизации (sync), который берёт книги из папки books/, строит из них дерево library/ и публикует его в целевое хранилище.

Запустить проект можно через Docker Compose: команда docker compose run --rm sync --create создаёт библиотеку, docker compose up -d поднимает сервер на localhost:3000. Образ Docker уже содержит инструменты для обработки обложек, cwebp и pdftoppm, поэтому обложки книг рендерятся корректно без ручной установки зависимостей на хост. Для запуска без Docker нужен Node 24 или новее и Unix-подобная система: инструмент синхронизации ищет свои графические утилиты через команду which, поэтому Windows не поддерживается.

Если под рукой нет своих книг, npm run demo создаёт девять сгенерированных книг в общественном достоянии (public domain), восемь EPUB и один PDF, чтобы можно было сразу посмотреть, как выглядит заполненная библиотека, не скачивая ничего лишнего. Названия и авторы у этих демо-книг настоящие и давно вне авторского права, а сам текст внутри, заглушка (placeholder).

Важная особенность: в проекте нет аутентификации вообще. Любой, кто может достучаться до запущенного приложения по сети, может читать и скачивать всю библиотеку целиком и переключаться между любыми профилями пользователей, документация прямо советует размещать сервис только в доверенной сети или за отдельным механизмом входа. Профили в проекте служат не барьером доступа, а лишь способом развести закладки и позиции чтения между разными людьми, читающими с одного сервера (например, соседями по дому). Для случаев, когда сервис всё же смотрит наружу, предусмотрен режим только для чтения, переменная окружения BOOKSHELF_READ_ONLY=1: хранилище продолжает отдавать книги, но перестаёт принимать любые изменения. В этом режиме нельзя добавлять, переименовывать или удалять профили, а позиции чтения перестают сохраняться на сервере и живут только в браузере, точно так же, как при хранилище, которое в принципе не умеет писать. Переключение между уже существующими профилями при этом продолжает работать, потому что это просто смена cookie, а не запись данных. Запрет на изменения проверяется там же, где происходит сама запись, а не скрытием кнопок в интерфейсе, поэтому обойти его прямым запросом к API не получится.

Ещё одно ограничение: если два устройства одновременно читают под одним и тем же профилем, положение чтения сохраняется по правилу «побеждает последняя запись» (last-write-wins), то есть более раннее сохранение может быть молча перезаписано более поздним. Код проекта распространяется по лицензии MIT; сама лицензия покрывает только код, авторские права на книги, которые пользователь положит в свою библиотеку, остаются между ним и правообладателями.

Ключевые факты

  • Bookshelf, self-hosted библиотека для электронных книг: одна страница со списком, поиском, скачиванием и встроенными читалками для EPUB и PDF
  • Работает в двух режимах: как Cloudflare Worker поверх объектного хранилища R2 без своего сервера, либо как обычный Node-сервер поверх папки на диске
  • Демо-режим генерирует 9 книг в общественном достоянии (8 EPUB и 1 PDF) для быстрого показа без скачивания реальных файлов
  • В проекте нет аутентификации: любой, кто достучится до сервиса по сети, может читать и скачивать всю библиотеку и любой профиль
  • Для публичного размещения предусмотрен режим только для чтения (BOOKSHELF_READ_ONLY=1), который блокирует запись на уровне обработки запросов, а не интерфейса

Почему это важно

Bookshelf решает узкую, но узнаваемую задачу для тех, кто хранит легальные электронные книги локально и хочет читать их с разных устройств без привязки к магазину или облачному сервису чтения. Технически интересен выбор архитектуры: проект можно развернуть либо совсем без сервера, как воркер Cloudflare поверх объектного хранилища R2, либо как классический Node-сервер над обычной папкой на диске, и в обоих случаях без создания отдельного аккаунта в самом приложении.

Кому это важно

В первую очередь, разработчикам и техническим энтузиастам, которые уже практикуют self-hosting (домашние медиасерверы, личные облака) и хотят добавить в этот набор читалку книг. Полезен и тем, кто делится книгами с домашними: профили в Bookshelf разводят закладки и позиции чтения между разными людьми на одном сервере, хотя и не ограничивают им доступ к самим файлам.

Как это применить

Развернуть можно через Docker Compose (docker compose run --rm sync --create, затем docker compose up -d), образ уже содержит инструменты обработки обложек cwebp и pdftoppm. Без Docker нужен Node 24 или новее и Unix-подобная система, так как инструмент синхронизации ищет графические утилиты через команду which, из-за чего Windows не поддерживается. Книги кладутся в папку books/, дальше npm run sync -- --create собирает библиотеку и публикует её в R2 или на диск. Быстро попробовать без своих файлов позволяет npm run demo, генерирующий девять книг в общественном достоянии. Проект распространяется по лицензии MIT, исходный код открыт на GitHub.

Можно ли доверять

Это опубликованный на GitHub open-source проект с открытым кодом под лицензией MIT, а не коммерческий продукт с маркетинговыми заявлениями, судить о нём можно напрямую по исходникам и документации. Источник (страница проекта) прямо и без прикрас честно описывает ограничения приложения, в том числе полное отсутствие аутентификации, это скорее говорит в пользу добросовестности документации, чем против неё.

Риски и подводные камни

Главный риск явно назван самими авторами: в приложении нет аутентификации, и любой, кто может достучаться до сервиса по сети, получает доступ на чтение и скачивание всей библиотеки, а также может переключаться между чужими профилями. Разворачивать Bookshelf в открытом интернете без отдельного слоя авторизации (VPN, прокси с логином и т.п.) означает открыть библиотеку кому угодно. Ещё одна тонкость: при одновременном чтении одного профиля с двух устройств позиция чтения сохраняется по принципу «последняя запись побеждает», более раннее сохранение может быть незаметно перезаписано более поздним, и это стоит иметь в виду при совместном использовании профилей.