Sign inSign up

nobbe/inkheart

By nobbe

•Updated about 2 months ago

Self-hosted PDF library

Image
0

10K+

nobbe/inkheart repository overview

⁠Inkheart

A self-hosted PDF library indexer and reader.

Inkheart Screenshot

⁠Platform Support

Inkheart is available as multi-architecture Docker images supporting:

  • AMD64 (x86_64) - Standard Intel/AMD processors
  • ARM64 (aarch64) - ARM-based systems including Raspberry Pi 4+, Apple Silicon, and ARM servers

Docker will automatically pull the correct image for your platform.

⁠Features

  • Filesystem based navigation
  • Embedded PDF.js reader
  • Direct linking to specific pages
  • Collections for organizing PDFs into custom groups
  • Pinned folders for quick sidebar access
  • Optional authentication via Firebase Auth with whitelisting
  • Light and dark color themes
  • Basic search

⁠Privacy & Telemetry

Inkheart sends non-identifying usage statistics to count active installations and guide development priorities.

What is tracked:

  • Server ping when index page loads (counted as one "active instance")
  • Version number
  • Library size bucket (e.g., "100-500 PDFs" - not exact counts)
  • Country-level location data
  • CPU architecture (e.g., x86_64, arm64)

Technical details:

  • Self-hosted Plausible Analytics (privacy-focused, no cookies, no persistent IDs)
  • Events labeled "pageview" represent instance activity, not user browsing

What is NOT tracked:

  • User pageviews, navigation, or reading behavior
  • File names, paths, or PDF contents
  • Any personally identifying information

Disabling telemetry:

Telemetry is enabled by default but easily disabled:

  • Before deployment: Set TELEMETRY_ENABLED=false in config
  • On first access: Click "Disable" in the consent banner
  • After setup: Toggle off in Settings → Privacy

⁠Limitations

  • Does not store metadata
  • Index is stored in-memory and may scale poorly for large libraries
  • Search pulls the entire index and filters on the client, scales poorly for large libraries.

⁠Setup with Docker Compose

You can pull the latest image from docker hub: https://hub.docker.com/r/nobbe/inkheart⁠ . Ensure that volume mounts already exist: e.g. mkdir /path/to/config /path/to/covers /path/to/thumbnails /path/to/media before running container to prevent permission issues.

example docker-compose.yml:

services:
  inkheart:
    image: nobbe/inkheart:latest
    container_name: inkheart
    network_mode: bridge
    ports:
      - 8080:8080/tcp
    volumes:
      - /path/to/media:/media # The path where you're storing your PDF files
      - /path/to/covers:/covers # This is where the first page of each file will be extracted to to serve as a library cover
      - /path/to/config:/config # Config folder, e.g for whitelist file
      - /path/to/thumbnails:/thumbnails # This folder will contain thumbnails generated for OpenGraph preview of pages when linking.
    environment:
      - MEDIA_DIR=/media
      - CONFIG_PATH=/config/inkheart.toml # path to a config file
      - BIND_ADDR=0.0.0.0 # Only needed if you want to change from default
    restart: always

⁠Serving from a Subdirectory

To serve Inkheart from a subdirectory (e.g., /pdfs), set the BASE_PATH environment variable:

environment:
  - BASE_PATH=/pdfs

Then configure your reverse proxy to forward requests. Example nginx configuration:

location /pdfs {
    proxy_pass http://inkheart:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Inkheart will be accessible at http://yourserver/pdfs.

⁠Config

The configuration is cumulative, meaning that values from different configuration sources are merged. Higher-priority sources take precedence over values from previous sources. The supported configuration sources are:

  1. Environment Variables

    • Hardcoded defaults are applied for variables not defined in the environment.
  2. Config File

    • Overrides environment config
    • TOML format

NOTE: The variable CONFIG_PATH is only read from the environment and can be used to set the location of your config file.

⁠Variables
VariableDescriptionDefault Value
CONFIG_PATHPath to configuration file. Only loaded from environment, ignored when read from config file"./inkheart.toml"
MEDIA_DIRDirectory for media files."/media"
IMAGE_DIRDirectory for cover images."/covers"
THUMBNAIL_DIRDirectory for thumbnails."/thumbnails"
BIND_ADDRAddress to bind the server to."127.0.0.1"
BIND_PORTPort to bind the server to."8080"
SCAN_INTERVALScan interval for re-indexing (in seconds)."600"
COVER_WIDTHWidth in pixels for the cover images.900
THUMBNAIL_WIDTHWidth in pixels for page thumbnails used in previews.300
BASE_PATHBase path for serving the application (e.g., /pdfs for multi-SPA setups)."/" (optional)
TELEMETRY_ENABLEDEnable anonymous usage statistics. See Privacy & Telemetry section for details.true
FIREBASE_CONFIG_PATHFirebase config json for authentication."./firebase.json" (optional)
FIREBASE_WHITELISTFile path for the whitelist of account IDs from Firebase.none (optional)
⁠TOML Configuration Example

Instead of setting all configuration options via environment variables, you can use a TOML configuration file. Below is an example that includes all available configuration options:

# inkheart.toml
# Note: CONFIG_PATH is only read from environment variables, not from this file

# Directory paths
MEDIA_DIR = "/media"
IMAGE_DIR = "/covers"
THUMBNAIL_DIR = "/thumbnails"

# Server configuration
BIND_ADDR = "0.0.0.0"
BIND_PORT = 8080
SCAN_INTERVAL = 600

# Image dimensions
COVER_WIDTH = 900
THUMBNAIL_WIDTH = 300

# Base path (optional)
# Useful when serving inkheart from a subdirectory
BASE_PATH = "/pdfs"

# Telemetry (see Privacy & Telemetry section for details)
TELEMETRY_ENABLED = true

# Firebase authentication (optional)
FIREBASE_CONFIG_PATH = "/config/firebase.json"
FIREBASE_WHITELIST = "/config/whitelist.cfg"

⁠Indexing

The application scans the given media directory immediately on startup and then schedules re-indexing with the interval specified. The application will display files in the same directory structure as in the media directory.

⁠Covers and Thumbnails directories

The application extracts the first page of each file found in the media directory to use as a high-res cover thumbnail. This extraction is done when a file is first indexed. As for thumbnails, these are extracted on demand as a link specifying a page number is either visited or linked to from a site that supports OpenGraph image previews. Thumbnails are extracted at a lower resolution.

NOTE: Files are indexed based on their path. If a file is moved to a different folder, or renamed, the indexing hash will not match and the cover will be extracted again.

⁠Authentication

⁠Firebase Authentication
  1. Create a Firebase project and enable the Authentication provider(s) of your choice (Sign-in with Google, email, etc).
  2. In your Firebase project settings, create a web app and get the Firebase configuration.
  3. Save the Firebase configuration as a JSON file in your config directory:
{
  "apiKey": "<API KEY>",
  "authDomain": "your-project.firebaseapp.com",
  "projectId": "your-project",
  "storageBucket": "your-project.appspot.com",
  "messagingSenderId": "1043858130670",
  "appId": "1:1043858130670:web:c1b1981cc04845939a55ff"
}
  1. Set the path to your Firebase config in FIREBASE_CONFIG_PATH environment variable (default: ./firebase.json).
⁠Firebase Whitelist

After signing in once you can open the Firebase Console and find the ID of the user(s) you'd like to whitelist rather than allow anyone with a Google account for example. The whitelist file should have one id per line, and the path to the whitelist is specified in the FIREBASE_WHITELIST config variable. After a restart only whitelisted users should be able to sign in.

⁠Support

If Inkheart is useful to you, consider supporting development:

ko-fi


GitLab: https://gitlab.com/Nystik/inkheart⁠
Version: 1.1.0 (Arbiter)
License: MIT

Tag summary

Content type

Image

Digest

sha256:ef393f770…

Size

29.3 MB

Last updated

about 2 months ago

docker pull nobbe/inkheart