需先创建 .env 并配置 DATABASE_URL、DB_USER、DB_PASSWORD 等变量,否则容器无法连接数据库;默认端口为 6060,需访问 http://localhost:6060 初始化管理员;所有书库必须建在宿主机挂载的目录内(如 /books);DISK_TYPE=NETWORK 时会禁用删除、移动、重命名等文件操作
docker compose up -dREADME 未说明具体硬件要求,仅要求 Docker 与 Docker Compose,并需搭配 MariaDB 容器运行
自托管的电子书、漫画和有声书数字图书馆,支持多用户与设备同步
自托管的电子书、漫画和有声书书库,支持 EPUB、AZW3、CBZ、CBR 等格式,可在线阅读并管理元数据。
核心能力
- 用规则过滤、标签和全文搜索构建动态书架
- 从 Google Books、Open Library、Amazon 抓取并编辑元数据
- 浏览器内置阅读器支持 PDF、EPUB、漫画及标注与进度追踪
- 通过 OPDS、Kobo、KOReader 同步阅读进度
- BookDrop 监控文件夹自动识别、补全元数据并排队导入
容易踩的坑
- v3.5.0Release v3.5.0最新正式版2026-09-21 · 2026-09-21 02:13 UTC
3.5.0 (2026-09-20)
This minor release primarily fixes three identified security issues in Grimmory:
- The
/api/v1/settingsendpoint allowed any user to access sensitive server settings. (GHSA-x6vg-344c-qrmv) - The upload feature did not restrict users to only uploading into libraries they had access to. (GHSA-7f4w-5hc7-j96r)
- An appropriately crafted epub could have lead to CPU / web server request thread exhaustion. (GHSA-mx77-3cq4-g227)
Changelog
Full Changelog: https://github.com/grimmory-tools/grimmory/compare/v3.4.1...v3.5.0
Features
- api: add metadata provider controller (#2673) (
402e89b) - reader: add epub reader tap navigation for mobile (#1909) (
c8a1a59)
Bug Fixes
- api: add library access check to uploads (#2648) (
2d7a3e9) - api: restrict settings by permission (#2647) (
2b66ca6) - api: exclude supplementary files from file type facet (#2688) (
e1d1c35) - api: include physical books in file type facet (#2687) (
765a340) - audiobook: sum folder track durations (#2684) (
bb44ce3) - opds: update opds references to be grimmory (#2659) (
5986e36) - progress: reset koreader device when coming from grimmory (#2640) (
a04652d) - ranobedb: use expected grimmory user agent (#2662) (
2dbac19) - readers: fix mobile text selection (#2667) (
6a778f8) - reader: stop unwanted page jumps when scrolling (#2699) (
1042cad)
Refactors
- api: add
BookParser.isEnabled()to test for enabled provider (#2694) (0b6689f) - api: remove unused book filters (#2690) (
f0ca4e5) - metadata: add external url to all metadata sources (#2670) (
b2fa4b7) - ui: drop frontend external URL generation (#2693) (
40cf653)
Dependencies
- The
- v3.4.1Release v3.4.12026-09-16 · 2026-09-16 00:03 UTC
查看更新说明
3.4.1 (2026-09-15)
This patch release fixes a bug with the OpenLibrary metadata search UI and avoids a service worker crash.
Changelog
Full Changelog: https://github.com/grimmory-tools/grimmory/compare/v3.4.0...v3.4.1
Bug Fixes
- angular: remove service worker api passthrough (#2638) (
539a0e0) - ui: modernise the metadata searcher component (#2631) (
ba47aaa)
Performance
- tests: use Angular recommended test config (#2632) (
6bfb345)
Refactors
- epub: make some epub extraction / creation code reusable (#2629) (
e6ac37f)
Contributors
We'd like to thank the contributors for this release for taking the time to make Grimmory better.
Including but not limited to: @alexhb1 @imnotjames
- angular: remove service worker api passthrough (#2638) (
- v3.4.0Release v3.4.02026-09-15 · 2026-09-15 01:42 UTC
查看更新说明
3.4.0 (2026-09-14)
Grimmory 3.4.0 introduces OpenLibrary & Apple Books Metadata Providers, fixes the existing GoodReads & Douban Metadata Providers, fixes bugs with epub generation, handles non-UTF8 headers in archives, and more.
Changelog
Full Changelog: https://github.com/grimmory-tools/grimmory/compare/v3.3.3...v3.4.0
Features
- kobo: show full Kobo API path in sync settings (#2381) (
852da00) - metadata: initial implementation of Apple Books source (#1780) (
0660e1d) - metadata: initial implementation of OpenLibrary source (#1764) (
9b38a09) - opds: add pagination to authors / series navigation (#2315) (
7d768a2) - api: add paged books sorts for author name / author sort name (#2497) (
f44a7df) - api: add paged books random sort (#2451) (
0e67549)
Bug Fixes
- amazon: emit external Amazon URL with region domain (#2330) (
4c160cd) - archive: handle non-utf8 ZIP headers with apache ZIP library (#2520) (
0279c15) - cbx: use natural compare that handles numbers larger than int (#2536) (
11224eb) - douban: ignore extraneous data when parsing window data (#2516) (
d75c128) - epub: add applebooks ID to template content.opf (#2616) (
a1b6233) - epub: handle duplicate zip entries when extracting epubs (#2526) (
75495bf) - epub: handle literal
+when decoding URLs (#2618) (ce18ce3) - epub: no flattening when sorting opf document elements (#2611) (
0b887ae) - epub: support cover edits when media type changes (#2281) (
828806a) - epub: support cover edits when no previous cover (#2278) (
e963f28) - goodreads: refresh goodreads public api token (#2477) (
8362a90) - i18n: use correct value for magicshelf.metadataFields.applebooksId (#2609) (
0ca234d) - library: refresh file size and hash for in-place modified files (#2490) (
7a9cd31) - magic-shelf: keep rule value on compatible operator change (#2604) (
81a40fd) - sidecar files are not written when only cover changes
- kobo: show full Kobo API path in sync settings (#2381) (
- v3.3.3Release v3.3.32026-08-22 · 2026-08-22 03:55 UTC
查看更新说明
3.3.3 (2026-08-21)
This patch release of Grimmory contains bug fixes for OIDC and introduces the environment variable
OIDC_ALLOW_UNSAFE_HOSTS.[!TIP] If you have a local identity provider that Grimmory is trying to use for OIDC, you will need to enable the
OIDC_ALLOW_UNSAFE_HOSTSenvironment variable flag.Changelog
Full Changelog: https://github.com/grimmory-tools/grimmory/compare/v3.3.2...v3.3.3
Bug Fixes
- api: use
FORCE_DISABLE_OIDCon all public / private OIDC flags (#2343) (662b327) - oidc: allow disable of SSRF filtering for OIDC config (#2413) (
1682a98) - ui: use signals in OIDC test connection (#2417) (
4ae1d0b)
Refactors
- oidc: use similar rest client config across OIDC (#2411) (
2be679a)
Internationalization
- update language for external API settings (#2341) (
7e7faee)
Dependencies
- bump the gradle-dependencies group in /backend with 2 updates (#2418) (
1634047)
- api: use
- v3.3.2Release v3.3.22026-08-19 · 2026-08-19 15:59 UTC
查看更新说明
3.3.2 (2026-08-19)
This patch release of Grimmory contains many bug fixes - including one security related bug fix.
The security fix (#2357) improves our mitigations against SSRF attacks via more complete filters on outbound requests - reported in https://github.com/grimmory-tools/grimmory/security/advisories/GHSA-8gxf-wjv6-jhjj by @tonghuaroot.
Changelog
Full Changelog: https://github.com/grimmory-tools/grimmory/compare/v3.3.1...v3.3.2
Bug Fixes
- api: add refresh token nbf to prevent immediate usage (#2245) (
c7d147c) - api: apply timeout to all restclient instances (#2321) (
ef041dd) - api: book files cannot be left in a detached state (#2389) (
eb5d390) - api: emit correct
Content-Typefor covers (#2285) (dfa81e3) - api: prevent NPE with default value in
MetadataUpdateWrapper(#2337) (41fa0c1) - api: stricter SSRF protections (#2357) (
31b574d) - api: use
ApiExceptioninstead ofEntityNotFoundExcepion(#2302) (e88de1a) - api: use
SetforBookEntity.bookFilesto mitigate duplicates (#2297) (f85ae0d) - api: wrap recalc match score in transaction to allow lazy load (#2332) (
dbd9106) - archive: ignore directories when streaming entries from zip (#2327) (
b24e104) - audible: emit external Audible URL with region domain (#2329) (
8fa769b) - audible: use expected URL patterns for product links (#2390) (
ddb9d3c) - books: prevent duplicate book file entries (#2289) (
c3b4593) - hardcover: use injected restclient with expected timeouts (#2320) (
9d15192) - ui: refresh duplicate merger after deleting books (#2284) (
97226de) - ui: use signals to make ISBN import reactive (#2324) (
42378ec)
Refactors
- amazon: use predefined domains (#2367) (
2a8d8ea) - ui: app-menu positioning and styling refinements (#2308) (
f617650) - ui: create metadata search provider anchor in template (#2317) (
536f6af)
Chores
- epub: avoid EpubContainer in EpubMetadataExtractor (#2128) ([`f
- api: add refresh token nbf to prevent immediate usage (#2245) (
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Grimmory is a self-hosted digital library for people who take their reading seriously.
Documentation · Quick Start · Translations · Discord · Releases
Features
| Feature | Description |
|---|---|
| Smart Shelves | Custom and dynamic shelves with rule-based filtering, tagging, and full-text search |
| Metadata Lookup | Covers, descriptions, reviews, and ratings pulled from Google Books, Open Library, and Amazon, all editable |
| Built-in Reader | Read PDFs, EPUBs, and comics in the browser with annotations, highlights, and reading progress tracking |
| Device Sync | Connect a Kobo, use any OPDS-compatible app, or sync progress with KOReader |
| Multi-User | Separate shelves, progress, and preferences per user with local or OIDC authentication |
| BookDrop | Drop files into a watched folder and Grimmory detects, enriches, and queues them for import automatically |
| One-Click Sharing | Send any book to a Kindle, an email address, or another user directly from the interface |
Supported Formats
| Category | Formats |
|---|---|
| eBooks | EPUB, MOBI, AZW, AZW3, FB2 |
| Documents | |
| Comics | CBZ, CBR, CB7 |
| Audiobooks | M4B, M4A, MP3, OPUS |
Quick Start
[!TIP] For OIDC setup, advanced configuration, or upgrade guides, see the full documentation.
Requirements: Docker and Docker Compose.
| Registry | Image |
|---|---|
| Docker Hub | grimmory/grimmory |
| GitHub Container Registry | ghcr.io/grimmory-tools/grimmory |
Step 1: Environment Configuration
Create a .env file:
# Application
APP_USER_ID=1000
APP_GROUP_ID=1000
TZ=Etc/UTC
# Database
DATABASE_URL=jdbc:mariadb://mariadb:3306/grimmory
DB_USER=grimmory
DB_PASSWORD=ChangeMe_Grimmory_2025!
# Optional: enable API docs + export OpenAPI JSON (defaults to false)
API_DOCS_ENABLED=false
# Storage: LOCAL (default) or NETWORK (disables file operations; see Network Storage section)
DISK_TYPE=LOCAL
# MariaDB
DB_USER_ID=1000
DB_GROUP_ID=1000
MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
MYSQL_DATABASE=grimmory
Step 2: Docker Compose
Stable images are published from semantic-release tags on main as vX.Y.Z plus latest. Nightly images are built from develop and tagged nightly.
Create a docker-compose.yml or copy and adapt deploy/compose/docker-compose.yml:
services:
grimmory:
image: grimmory/grimmory:latest
# Convenience tag:
# image: grimmory/grimmory:<release-version>
# Alternative: ghcr.io/grimmory-tools/grimmory:<release-version>
# To build from source instead: comment out 'image' and uncomment below
# build: .
container_name: grimmory
environment:
- USER_ID=${APP_USER_ID}
- GROUP_ID=${APP_GROUP_ID}
- TZ=${TZ}
- DATABASE_URL=${DATABASE_URL}
- DATABASE_USERNAME=${DB_USER}
- DATABASE_PASSWORD=${DB_PASSWORD}
- API_DOCS_ENABLED=${API_DOCS_ENABLED}
- DISK_TYPE=${DISK_TYPE}
depends_on:
mariadb:
condition: service_healthy
ports:
- "6060:6060"
volumes:
- ./data:/app/data
- ./books:/books
- ./bookdrop:/bookdrop
healthcheck:
test: wget -q -O - http://localhost:6060/api/v1/healthcheck
interval: 60s
retries: 5
start_period: 60s
timeout: 10s
restart: unless-stopped
mariadb:
image: lscr.io/linuxserver/mariadb:11.4.5
environment:
- PUID=${DB_USER_ID}
- PGID=${DB_GROUP_ID}
- TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- ./mariadb/config:/config
restart: unless-stopped
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 10
Step 3: Launch
docker compose up -d
Open http://localhost:6060, create your admin account, and start building your library. (All libraries must be created within directories mounted on the host, e.g. the /books/ directory in the sample docker-compose.yml above.)
Optional: Capture Heap Dumps for OOM Debugging
Heap dumps are disabled by default. To enable them temporarily, add the following environment variable to the grimmory service:
services:
grimmory:
environment:
- JDK_JAVA_OPTIONS=-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/data
The JVM creates a PID-specific .hprof file in the mounted /app/data directory. Remove the option after collecting the diagnostic data because heap dumps can be large and contain sensitive application data.
Additional deployment examples:
- Docker Compose:
deploy/compose/docker-compose.yml - Helm:
deploy/helm/grimmory/Chart.yaml - Podman Quadlet:
deploy/podman/quadlet/README.md
Developer Surfaces
Contributor workflow, PR policy, and release semantics live in CONTRIBUTING.md. Non-English translation contributions are managed through Crowdin.
General purpose development guidelines live in DEVELOPMENT.md. Component-specific implementation guidance lives in:
The root Justfile is the primary local command surface and mirrors the folder-local backend/Justfile and frontend/Justfile entrypoints.
just # Show root + api + ui recipes
just test # Run backend and frontend tests
just api test # Run backend tests only
just ui dev # Start the frontend dev server
API Reference Docs
When enabled via API_DOCS_ENABLED, API reference documentation is available as both an openapi.json and as publicly accessible docs. The endpoints are:
- API reference docs are available at
http://localhost:6060/api/docs - OpenAPI JSON is available at
http://localhost:6060/api/openapi.json
BookDrop
Drop book files into a watched folder. Grimmory picks them up, pulls metadata, and queues them for your review.
graph LR
A[Drop Files] --> B[Auto-Detect]
B --> C[Extract Metadata]
C --> D[Review and Import]
| Step | What Happens |
|---|---|
| 1. Watch | Grimmory monitors the BookDrop folder continuously |
| 2. Detect | New files are picked up and parsed automatically |
| 3. Enrich | Metadata is fetched from Google Books and Open Library |
| 4. Import | You review, adjust if needed, and add to your library |
Mount the volume in docker-compose.yml:
volumes:
- ./bookdrop:/bookdrop
Network Storage
Set DISK_TYPE=NETWORK in your .env to run Grimmory against a network-mounted file system (NFS, SMB, etc.).
In this mode, direct file operations (delete, move, rename from the UI) are disabled to avoid destructive changes on shared mounts.
All other features — reading, metadata, sync — remain fully functional.
Community and Support
| Channel | |
|---|---|
| Report a bug | Open an issue |
| Request a feature | Open a Discussion |
| Contribute | Contributing Guide |
| Join the discussion | Discord Server |
[!WARNING] Before opening a pull request, open an issue first and get maintainer approval. Pull requests without a linked issue, without screenshots or video proof, or without pasted test output will be closed. All code must follow the project backend and frontend conventions. AI-assisted contributions are welcome, but you must run, test, and understand every line you submit. See the Contributing Guide for full details.
License
Distributed under the terms of the AGPL-3.0 License.