shelf docs
GitHub

Running Shelf

Running on a server

HTTPS and a reverse proxy

Passwords, device keys, and passkeys need HTTPS on any shelf reached from outside your own network. The usual way is a reverse proxy that holds the certificate and passes requests to Shelf. Tell Shelf it is there with Hosting:BehindProxy set to true, so it trusts the proxy's forwarded headers, and only when Shelf can't be reached except through it.

Caddy

Caddy gets and renews a certificate by itself:

shelf.example.org {
    reverse_proxy localhost:8080
}

nginx

server {
    listen 443 ssl;
    server_name shelf.example.org;
    # ssl_certificate and ssl_certificate_key, from Let's Encrypt, say

    client_max_body_size 1100m;   # audiobooks can be up to 1 GB; raise it with Uploads:MaxAudioMegabytes

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 1h;
    }
}

The Upgrade lines matter: Shelf's pages keep a WebSocket open to the server.

Tip

Set Email:PublicAddress and Passkeys:Origin to the address readers use, such as https://shelf.example.org, so links in emails and passkeys are right.

Without a proxy, Shelf sends HSTS and redirects HTTP to HTTPS whenever it has an HTTPS port of its own.

OCR for scanned PDFs

Reading scanned pages needs Tesseract and Poppler. The Docker image has both, with English. From source, install them yourself; Shelf looks for tesseract, pdftoppm, pdftotext, and pdfinfo on the path when it starts.

# Debian and Ubuntu
sudo apt install tesseract-ocr tesseract-ocr-eng poppler-utils

# Arch Linux
sudo pacman -S tesseract tesseract-data-eng poppler

# macOS
brew install tesseract poppler

For other languages, install their Tesseract data and list them in Ocr:Languages, such as eng+fra. In Docker, extend the image:

FROM ghcr.io/doodersrage/shelf:latest
USER root
RUN apt-get update && apt-get install -y --no-install-recommends tesseract-ocr-fra && rm -rf /var/lib/apt/lists/*
USER app

Each PDF is read once, a page at a time, and the words are kept in the database, so a restart carries on where it stopped.

Calibre for Kindle files

Kindle files are turned into EPUBs by Calibre's ebook-convert. Install Calibre on the server, or build the Docker image with it:

docker build --build-arg CALIBRE=true -t shelf https://github.com/doodersrage/shelf.git

Email

Email lets readers reset a forgotten password themselves and get their notifications by email, which is on for each reader until they turn it off. Readers sign in with their email address whether or not the shelf can send email. Any SMTP server works: your email provider's, or a service such as Fastmail, Mailgun, or Amazon SES. Configuration lists the settings. Readers can send themselves a test from Account once their address is saved.

Disk space

Plan for your files more than Shelf itself: e-books are a few megabytes each, audiobooks a few hundred, and the database stays small. Held uploads that nobody decided on are cleared after a day.

When buttons do nothing

Most buttons on Shelf's pages work through a live connection to the server (a WebSocket, or a slower fallback when that is not allowed). If it cannot start, a banner at the bottom of the page says so. The usual causes:

  • A browser extension that blocks scripts or WebSockets, such as uBlock Origin in advanced mode, NoScript, or Privacy Badger. Allow your Shelf's address in it, then reload.
  • A reverse proxy that does not pass WebSockets on. In nginx, add proxy_http_version 1.1; and the Upgrade and Connection headers; Caddy and Traefik pass them on by themselves.
  • A strict corporate or school network that blocks WebSockets.

Links and forms work without the connection. In the browser's developer tools, the page's <html> element carries data-live: connected when all is well, failed when the connection could not start.

How big a library can be

Shelf was tried with a library of 10,000 books, 2,000 of them with an e-book, on a desktop computer (a 12-core Ryzen 9, so a Raspberry Pi or a small NAS will be a few times slower):

What Time
The library, any view about 140 ms
Stats about 220 ms
A book's page, Authors, Series, Shelves, Quotes under 20 ms
Search inside books under 10 ms
All books as JSON (7 MB) about 200 ms
A snapshot of the whole server about 140 ms

The server used about 75 MB of memory for it. The library draws 60 books at a time, so a long list stays quick in the browser too.