Shelfmark Enhanced is a community fork of Shelfmark by CaliBrain β with added SSO, VPN integration, UI enhancements, and a refactored codebase. It is fully open source, free to use, and no commercial version exists.
Shelfmark is a self-hosted web interface for searching and requesting books and audiobooks across multiple sources. Bring your own sources, metadata providers, and download clients to build a single hub for your digital library. Supports multiple users with a built-in request system, so you can share your instance with others and let them browse and request books on their own.
Works great alongside the following library tools, with support for automatic imports:
- One-Stop Interface - A clean, modern UI to search, browse, and download from multiple configured sources in one place
- Multiple Sources - Configurable web, torrent, usenet, and IRC source support
- Audiobook Support - Full audiobook search and download with dedicated processing
- Flexible Search - Search metadata providers (Hardcover, Open Library, Google Books) for rich book and audiobook discovery, or query configured sources directly
- Multi-User & Requests - Share your instance with others, let users browse and request books, and manage approvals with configurable notifications
- Authentication - Built-in login, OIDC single sign-on, proxy auth, and Calibre-Web database support
- Real-Time Progress - Unified download queue with live status updates across all sources
- Network Flexibility - Configurable proxy support, DNS settings, and optional Cloudflare handling for protected sources
- Docker & Docker Compose
-
Download the docker-compose file:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.yml
-
Start the service:
docker compose up -d
-
Open
http://localhost:8084
Open the web interface, then configure the sources and settings you want to use.
volumes:
- /your/config/path:/config # Config, database, and artwork cache directory
- /your/download/path:/books # Downloaded books
- /client/path:/client/path # Optional: For Torrent/Usenet downloads, match your client directory exactly.Tip: Point the download volume to your CWA or Grimmory ingest folder for automatic import.
Note: CIFS shares require
nobrlmount option to avoid database lock errors.
- Start the container as
1000:1000with Dockeruser: "1000:1000"ordocker run --user 1000:1000. - For Kubernetes, set
runAsUser: 1000,runAsGroup: 1000, andrunAsNonRoot: truetogether. PUID/PGIDkeep the default root startup flow.- Mounted paths must already be writable by
1000:1000. USING_TOR=truerequires root startup.
Direct
- Queries configured sources directly
Universal (recommended)
- Search via metadata providers (Hardcover, Open Library, Google Books) for richer results
- Aggregates releases from multiple configured sources
- Full audiobook support
Environment variables work for initial setup and Docker deployments. They serve as defaults that can be overridden in the web interface.
| Variable | Description | Default |
|---|---|---|
FLASK_PORT |
Web interface port | 8084 |
INGEST_DIR |
Book download directory | /books |
TZ |
Container timezone | UTC |
PUID / PGID |
Runtime user/group for the default root-startup flow | 1000 / 1000 |
SEARCH_MODE |
direct or universal |
universal |
USING_TOR |
Enable Tor routing (requires root startup) | false |
See the full Environment Variables Reference for all available options.
Some of the additional options available in Settings:
- Prowlarr - Configure indexers and download clients to download books and audiobooks
- Additional audiobook sources - Configure additional sources for audiobook discovery
- IRC - Add details for IRC book sources and download directly from the UI
- Library Link - Add a link to your Calibre-Web or Grimmory instance in the UI header
- File processing - Customiseable download paths, file renaming and directory creation with template-based renaming
- Network Settings - Custom proxy support (SOCKS5 + HTTP/S) and configurable DNS
- Format & Language - Filter downloads by preferred formats, languages and sorting order
- Metadata Providers - Configure API keys for Hardcover, Open Library, etc.
docker compose up -dThe full-featured image with all network capabilities included.
Optional Tor support for network privacy:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.tor.yml
docker compose -f docker-compose.tor.yml up -dNotes:
- Requires root startup
- Requires
NET_ADMINandNET_RAWcapabilities - Timezone is auto-detected from Tor exit node
- Custom DNS/proxy settings are ignored when Tor is active
A lighter image without the built-in browser automation. Ideal for:
- External services - Already running FlareSolverr or similar for other applications
- Alternative sources - Using Prowlarr, IRC, or other configured sources
- Audiobooks - Using Shelfmark primarily for audiobooks
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.lite.yml
docker compose -f docker-compose.lite.yml up -dIf you need browser-based access with the Lite image, configure an external resolver in Settings.
Authentication is optional but recommended for shared or exposed instances. Multiple authentication methods are available in Settings:
1. Single Username/Password
2. Proxy (Forward) Authentication
Proxy auth trusts headers set by your reverse proxy (e.g. X-Auth-User). Ensure Shelfmark is not directly exposed, and configure your proxy to strip/overwrite these headers for all inbound requests.
3. OIDC (OpenID Connect)
Integrate with your identity provider (Authelia, Authentik, Keycloak, etc.) for single sign-on. Supports PKCE flow, auto-discovery, group-based admin mapping, and auto-provisioning of new users.
4. Calibre-Web Database
If you're running Calibre-Web, you can reuse its user database by mounting it:
volumes:
- /path/to/calibre-web/app.db:/auth/app.db:roWith any authentication method enabled, Shelfmark supports multi-user management with admin/user roles. Users can have per-user settings for download destinations, email recipients, and notification preferences. Non-admin users only see their own downloads and can submit book requests for admin review. Admins can configure request policies per source to control whether users can download directly, must submit a request, or are blocked entirely.
Shelfmark is a manual search and download tool, the entry point to your book library, not a library manager. It finds books, downloads them, and sends them to a configured destination. That's the full scope.
Shelfmark intentionally does not:
- Track or manage your library - it doesn't know or care what you already own
- Integrate with library software - what happens after delivery is up to your library tool
- Monitor authors, series, or new releases - there is no background automation
- Queue future downloads - if a book isn't available now, Shelfmark won't watch for it
These are non-goals, not missing features.
The application exposes a health endpoint at /api/health (no authentication required). Add a health check to your compose:
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8084/api/health"]
interval: 30s
timeout: 30s
retries: 3Logs are available via:
docker logs <container-name>/var/log/shelfmark/inside the container (whenENABLE_LOGGING=true)
Log level is configurable via Settings or LOG_LEVEL environment variable.
# Quality checks
make checks # Run ALL static analysis (frontend + Python)
make python-checks # Run Ruff, BasedPyright, and Vulture
make install-python-dev # Sync Python runtime + dev tools with uv
# Frontend development
make install # Install dependencies
make dev # Start Vite dev server (localhost:5173)
make build # Production build
make frontend-typecheck # TypeScript checks
# Backend (Docker)
make up # Start backend via docker-compose.dev.yml
make down # Stop services
make refresh # Rebuild and restart
make restart # Restart containerThe frontend dev server proxies to the backend on port 8084.
A community fork β all original Shelfmark features are fully preserved. The project scope is unchanged.
| Feature | Shelfmark (upstream) | Shelfmark Enhanced |
|---|---|---|
| Authentication | Local login, OIDC, proxy auth | + SAML2 SSO (Authentik, Keycloak, Okta, Azure AD) |
| Session management | Basic sessions | Session invalidation, forced re-auth on config change |
| User management | Config file | Users admin page β create, edit, disable users in the UI |
| VPN integration | None | Gluetun status β live VPN indicator in the header; kill-switch routing via compose overlay |
| Home screen | Plain search bar | Floating book-cover parallax animation in the background |
| Library view | Simple download list | Book shelf grid with animated 3D open-book detail modal |
| Download visibility | Private only | Public / Private toggle per download, persisted per user |
| Code quality | Original structure | Refactored main.py and settings.py; cleaned module layout |
| Docker image | Build-only | Pre-built multi-platform image (amd64 + arm64) published to GHCR |
- Docker & Docker Compose
docker-compose.yml
services:
shelfmark:
image: ghcr.io/shelfmark-enhanced/enhanced-shelfmark:latest
container_name: shelfmark
environment:
PUID: 1000
PGID: 1000
ports:
- "6060:8084"
volumes:
- /path/to/books:/books
- /path/to/config:/config
restart: unless-stoppeddocker compose up -dOpen http://localhost:6060 and complete the setup wizard.
Route all Shelfmark traffic through a VPN using Gluetun. The overlay moves the port binding onto the Gluetun container so all outbound traffic is VPN-routed. The header will display a live VPN connected/disconnected pill.
docker-compose.yml (base β no ports: block needed here)
services:
shelfmark:
image: ghcr.io/shelfmark-enhanced/enhanced-shelfmark:latest
container_name: shelfmark
environment:
PUID: 1000
PGID: 1000
volumes:
- /path/to/books:/books
- /path/to/config:/config
restart: unless-stoppeddocker-compose.gluetun.yml (overlay β applied on top with -f)
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- "6060:8084" # Shelfmark UI (port moved here from shelfmark service)
- "127.0.0.1:8000:8000" # Gluetun HTTP control API (for VPN status indicator)
environment:
VPN_SERVICE_PROVIDER: "${VPN_SERVICE_PROVIDER}" # e.g. mullvad, nordvpn, expressvpn
VPN_TYPE: "${VPN_TYPE}" # wireguard or openvpn
WIREGUARD_PRIVATE_KEY: "${WIREGUARD_PRIVATE_KEY}" # WireGuard only
WIREGUARD_ADDRESSES: "${WIREGUARD_ADDRESSES}" # WireGuard only
OPENVPN_USER: "${OPENVPN_USER}" # OpenVPN only
OPENVPN_PASSWORD: "${OPENVPN_PASSWORD}" # OpenVPN only
SERVER_COUNTRIES: "${SERVER_COUNTRIES:-}" # Optional server selection
HTTP_CONTROL_SERVER_ADDRESS: ":8000"
# Port is bound to 127.0.0.1 only, so public access is safe here
HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE: public
restart: unless-stopped
volumes:
- gluetun_data:/gluetun
shelfmark:
network_mode: "service:gluetun"
depends_on:
- gluetun
ports: !reset []
volumes:
gluetun_data:.env (never commit this file β add it to .gitignore)
VPN_SERVICE_PROVIDER=mullvad
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your-private-key-here
WIREGUARD_ADDRESSES=10.x.x.x/32
SERVER_COUNTRIES=NetherlandsStart with both compose files:
docker compose -f docker-compose.yml -f docker-compose.gluetun.yml up -dFull Gluetun provider docs and credential setup: https://github.com/qdm12/gluetun/wiki
All upstream authentication methods are available. Shelfmark Enhanced adds:
auth:
mode: saml2
saml2:
idp_metadata_url: "https://auth.example.com/api/v3/sso/saml/metadata/"
sp_entity_id: "shelfmark"
sp_acs_url: "https://shelfmark.example.com/auth/saml/acs"
attribute_mapping:
username: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"auth:
mode: oidc
oidc:
issuer_url: "https://auth.example.com/application/o/shelfmark/"
client_id: "your-client-id"
client_secret: "your-client-secret"
redirect_uri: "https://shelfmark.example.com/auth/callback"auth:
mode: proxy
proxy:
username_header: "Remote-User"
email_header: "Remote-Email"Images are published to the GitHub Container Registry on every release:
| Tag | Description |
|---|---|
latest |
Latest stable release |
1.0.0, 1.0, 1 |
Pinned semantic version (recommended for production) |
dev |
Latest build from production / development branch |
Full image (all features including SAML2):
ghcr.io/shelfmark-enhanced/enhanced-shelfmark:latest
Lite image (smaller footprint, no SAML2):
ghcr.io/shelfmark-enhanced/enhanced-shelfmark-lite:latest
Both images are built for linux/amd64 and linux/arm64.
git clone https://github.com/shelfmark-enhanced/shelfmarkenhanced.git
cd shelfmarkenhanced
docker compose -f compose/docker-compose.enhanced.yml up --build -dPull requests are welcome. For significant changes please open an issue first to discuss what you'd like to change.
- Fork the repo
- Create a feature branch off
development(git checkout -b feat/my-feature) - Commit your changes
- Push and open a PR against
development
Production releases are merged from development β production and tagged with a semver version (e.g. v1.0.0).
MIT License β Copyright (c) 2024 CaliBrain. See LICENSE for the full text.
Also released under the MIT License β Copyright (c) 2025 Shelfmark Enhanced Contributors.
Open source, free to use. No commercial version of Shelfmark Enhanced exists or is planned. If you encounter anyone selling this software, they are not affiliated with this project.
Fork attribution. Shelfmark Enhanced is an independent community project. It is not affiliated with, endorsed by, or supported by CaliBrain or the original Shelfmark project.
No warranty. This software is provided "as is", without warranty of any kind. Use it at your own risk.
Your responsibility. You are solely responsible for ensuring your use complies with the laws of your jurisdiction and the terms of service of any sources you configure.
Shelfmark (upstream and Enhanced) is a search interface that displays results from external metadata providers and sources. It does not host, store, or distribute any content. The developers are not responsible for how the tool is used or what is accessed through it.
Users are solely responsible for:
- Ensuring they have the legal right to download any material they access
- Complying with copyright laws and intellectual property rights in their jurisdiction
- Understanding and accepting the terms of any sources they configure
Use of this tool is entirely at your own risk.
For upstream Shelfmark support: github.com/calibrain/shelfmark/issues




