Grimmory
Self-hosted book management — successor to BookLore. Organize your library with smart shelves, built-in reader, metadata lookup, and sync to Kobo and KOReader devices.
| Registry | ghcr.io/daemonless/grimmory |
| Source | https://github.com/grimmory-tools/grimmory |
| Website | https://grimmory.org/ |
Features
- Smart Shelves — Rule-based filtering, tagging, and full-text search
- Built-in Reader — In-browser reading for PDFs, EPUBs, and comics with annotations and progress tracking
- Metadata Lookup — Book info from Google Books, Open Library, and Amazon (fully editable)
- Device Sync — Kobo compatibility, OPDS support, and KOReader synchronization
- BookDrop — Drop files into a watched folder; Grimmory detects, enriches metadata, and queues for review
- Multi-User — Individual shelves and preferences with local or OIDC authentication
- One-Click Sharing — Send books to Kindle, email, or other users
Supported formats: EPUB, MOBI, AZW, AZW3, FB2, PDF, CBZ, CBR, CB7, M4B, M4A, MP3, OPUS
Version Tags
| Tag | Description | Best For |
|---|---|---|
latest |
Upstream Binary. Built from official release. | Most users. Matches Linux Docker behavior. |
Prerequisites
Before deploying, ensure your host environment is ready. See the Quick Start Guide for host setup instructions.
Deploy
Save as compose.yaml and run podman-compose up -d:
name: grimmory
services:
grimmory:
image: ghcr.io/daemonless/grimmory:latest
container_name: grimmory
network_mode: host
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- DATABASE_URL=jdbc:mariadb://127.0.0.1:3306/grimmory
- DATABASE_USERNAME=grimmory
- DATABASE_PASSWORD=changeme
- SWAGGER_ENABLED=false
- FORCE_DISABLE_OIDC=false
volumes:
- grimmory-data:/app/data
- /path/to/books:/books
- grimmory-bookdrop:/bookdrop
depends_on:
- mariadb
restart: unless-stopped
mariadb:
image: ghcr.io/daemonless/mariadb:latest
container_name: grimmory-mariadb
network_mode: host
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- MYSQL_ROOT_PASSWORD=changeme
- MYSQL_DATABASE=grimmory
- MYSQL_USER=grimmory
- MYSQL_PASSWORD=changeme
volumes:
- grimmory-mariadb:/config
restart: unless-stopped
volumes:
grimmory-data:
grimmory-bookdrop:
grimmory-mariadb:
Access Grimmory at http://your-host:6060
# Start MariaDB first
podman run -d --name grimmory-mariadb \
--network host \
-e PUID=1000 -e PGID=1000 -e TZ=Etc/UTC \
-e MYSQL_ROOT_PASSWORD=changeme \
-e MYSQL_DATABASE=grimmory \
-e MYSQL_USER=grimmory \
-e MYSQL_PASSWORD=changeme \
-v /path/to/containers/grimmory/mariadb:/config \
ghcr.io/daemonless/mariadb:latest
# Then start Grimmory
podman run -d --name grimmory \
--network host \
-e PUID=1000 -e PGID=1000 -e TZ=Etc/UTC \
-e DATABASE_URL=jdbc:mariadb://127.0.0.1:3306/grimmory \
-e DATABASE_USERNAME=grimmory \
-e DATABASE_PASSWORD=changeme \
-v /path/to/containers/grimmory/data:/app/data \
-v /path/to/books:/books \
-v /path/to/containers/grimmory/bookdrop:/bookdrop \
ghcr.io/daemonless/grimmory:latest
Parameters
Environment Variables
| Variable | Default | Description |
|---|---|---|
PUID |
1000 |
User ID |
PGID |
1000 |
Group ID |
TZ |
Etc/UTC |
Timezone |
DATABASE_URL |
jdbc:mariadb://127.0.0.1:3306/grimmory |
MariaDB JDBC connection URL |
DATABASE_USERNAME |
grimmory |
Database username |
DATABASE_PASSWORD |
changeme |
Database password |
SWAGGER_ENABLED |
false |
Enable Swagger UI |
FORCE_DISABLE_OIDC |
false |
Force-disable OIDC authentication |
DISK_TYPE |
— | Set to NETWORK for NFS/SMB mounts (disables destructive file ops) |
JAVA_TOOL_OPTIONS |
— | Additional JVM options (e.g., -Xmx512m to cap memory) |
Volumes
| Path | Description |
|---|---|
/app/data |
Application data and configuration |
/books |
Book library directory |
/bookdrop |
Drop folder for automatic imports |
Ports
| Port | Description |
|---|---|
6060 |
Web interface |
Networking
The default compose uses network_mode: host — both containers communicate via 127.0.0.1. Only port 6060 needs to be exposed externally.
For isolated networking (multiple stacks, no port conflicts), use bridge mode with the dnsname CNI plugin:
services:
grimmory:
# remove network_mode: host, add:
ports:
- "6060:6060"
environment:
DATABASE_URL: "jdbc:mariadb://mariadb:3306/grimmory"
mariadb:
# remove network_mode: host
# container name becomes the DNS hostname
Migration from BookLore
Grimmory is the direct successor to BookLore and auto-migrates existing data on first start.
- Stop the BookLore container
- Copy
/containers/booklore/to/containers/grimmory/ - Deploy Grimmory pointing at the same MariaDB data
- Grimmory will migrate the schema on startup
The MariaDB data format is compatible between BookLore and Grimmory.
BookDrop
BookDrop watches the /bookdrop volume for new files. Drop any supported file in and Grimmory will:
- Detect the new file
- Extract and look up metadata
- Queue it for your review before adding to the library
NFS/SMB tip: If /bookdrop is on a network share, set DISK_TYPE=NETWORK to prevent destructive file operations on shared mounts.
Architectures: amd64
User: bsd (UID/GID via PUID/PGID, defaults to 1000:1000)
Base: FreeBSD 15.0
Need help? Join our Discord community.