Self-Hosted E-Book Library with Calibre-Web on Docker: Manage, Read, and Sync Books Anywhere

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

The Problem: Scattered E-Books and No Good Way to Access Them

If you’ve been collecting e-books for a while, you know the pain. PDFs on your laptop, EPUBs on an old USB drive, a handful of AZW3 files from Kindle — scattered across devices with no single place to manage them. Cloud services like Google Play Books or Apple Books lock you into their ecosystems. Kindle requires you to buy from Amazon. What you actually want is something simpler: a private library you control, accessible from any browser, on any device.

I hit this exact wall a few years back. I had over 300 technical books — Linux guides, Docker references, programming tutorials — and no clean way to organize or read them outside my main workstation. Calibre-Web on Docker fixed that. It’s now a permanent fixture in my HomeLab alongside Nextcloud and Gitea.

What Calibre-Web Actually Is

Worth taking 60 seconds to understand the architecture before diving into Docker commands.

Calibre is a mature desktop application for managing e-book collections. It stores everything in a folder-based library with a metadata.db SQLite file that tracks books, authors, covers, and metadata.

Calibre-Web is a separate open-source project that reads that same library folder and exposes it through a clean web interface. You get:

  • A searchable, filterable book catalog
  • In-browser reading (EPUB format via the built-in reader)
  • OPDS catalog support — so e-reader apps like KOReader or Moon+ can pull books directly
  • User accounts so you can share access with family
  • Send-to-Kindle and send-to-email features
  • Book format conversion (optional, requires Calibre binary installed)

The key architectural point: Calibre-Web does not store books itself. It reads from your Calibre library folder. Your actual files stay in a plain directory — no proprietary database migrations, no vendor lock-in.

Prerequisites

You need:

  • A Linux server or NAS (even a Raspberry Pi 4 with 2GB RAM handles this fine)
  • Docker and Docker Compose installed
  • An existing Calibre library, or a willingness to create one

No Calibre library yet? Install the Calibre desktop app on your PC and add a few books. It generates a library folder containing metadata.db and author subfolders. Copy that entire folder to your server and you’re ready.

Setting Up the Directory Structure

On your server, create the two folders Calibre-Web needs:

mkdir -p ~/calibre/config
mkdir -p ~/calibre/library

The library folder is where your Calibre library lives — the one with metadata.db. The config folder is where Calibre-Web stores its own settings, user database, and cache.

Already have a Calibre library on your PC? Copy it over:

scp -r /path/to/Calibre\ Library/ user@your-server:~/calibre/library/

Writing the Docker Compose File

Create docker-compose.yml inside ~/calibre/:

version: "3.8"

services:
  calibre-web:
    image: lscr.io/linuxserver/calibre-web:latest
    container_name: calibre-web
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - DOCKER_MODS=linuxserver/mods:universal-calibre  # optional: enables format conversion
    volumes:
      - ./config:/config
      - ./library:/books
    ports:
      - "8083:8083"
    restart: unless-stopped

A few things worth explaining here:

  • PUID and PGID — set these to match your Linux user ID. Run id -u and id -g to check. Mismatched values are the #1 cause of permission errors on startup.
  • TZ — set your timezone so timestamps display correctly.
  • DOCKER_MODS=linuxserver/mods:universal-calibre — this optional mod installs the full Calibre binary inside the container, enabling format conversion (e.g., EPUB → MOBI). Skip it if you don’t need conversion; it adds 3–5 minutes to the first startup.
  • The /books mount is where Calibre-Web expects to find your library.

Starting the Container

cd ~/calibre
docker compose up -d

Check the logs to confirm it started cleanly:

docker compose logs -f calibre-web

On a typical VPS or home server, it’s listening within 10–15 seconds (longer if you enabled the Calibre mod — see above). Open http://your-server-ip:8083 in your browser.

First-Time Configuration

The first screen asks for your Calibre library path. Enter /books — that’s the container-side mount point from the compose file.

Default login credentials:

  • Username: admin
  • Password: admin123

Change the admin password immediately: go to Admin → Edit User → admin and update it before doing anything else.

From the admin panel, you can also:

  • Enable or disable new user registration (disable it for a private setup)
  • Configure SMTP settings for the send-to-Kindle feature
  • Enable Goodreads integration for book metadata lookup

Setting Up the OPDS Catalog for E-Reader Apps

Honestly, this is the feature that makes the whole thing worth it. OPDS (Open Publication Distribution System) is a standard catalog format understood by most e-reader apps. Once configured, KOReader, Aldiko, and Moon+ Reader can browse and download books directly from your Calibre-Web instance — no side-loading, no cables.

In Calibre-Web, go to Admin → Basic Configuration → Feature Configuration and enable Anonymous browsing if you want the OPDS feed accessible without login. Useful for trusted home networks.

Your OPDS feed URL will be:

http://your-server-ip:8083/opds

In KOReader: Search → OPDS catalog → Add catalog, paste the URL, done. Your entire library shows up browsable from your e-reader.

Exposing Calibre-Web Outside Your Home Network

Two practical options here:

Option 1: Reverse Proxy with NGINX or Caddy

Already running a reverse proxy in your HomeLab? Add a block for Calibre-Web. With Caddy, it’s four lines:

books.yourdomain.com {
    reverse_proxy localhost:8083
}

Caddy handles HTTPS automatically via Let’s Encrypt. No certificate management needed.

Option 2: Tailscale (Simpler for Beginners)

Running Tailscale already? Your Calibre-Web port is reachable via the Tailscale IP without any port forwarding or DNS configuration. Just hit http://100.x.x.x:8083 from any Tailscale-connected device. This is what I use on the road.

Keeping Your Library Updated

Add new books using the Calibre desktop app as usual. Changes write to metadata.db in the shared folder, and Calibre-Web picks them up automatically. No container restart required — just refresh the browser.

To update the container when a new Calibre-Web version drops:

cd ~/calibre
docker compose pull
docker compose up -d

The linuxserver.io image keeps latest pinned to the current stable release, so these three commands are all you need.

A Few Things I Learned the Hard Way

After running this setup for two years, here are the gotchas to watch for:

  • Permission errors on startup: Almost always a PUID/PGID mismatch. Run id on your server user and confirm the values match the compose file.
  • metadata.db locked: If Calibre desktop is open on your PC and the library is mounted via NFS to your server, SQLite file locking causes conflicts. Close the desktop app before Calibre-Web tries to write to the database.
  • OPDS not showing all books: Some OPDS clients cap results at 30 per page. If your catalog looks incomplete, check the client’s settings for catalog page size.
  • Format conversion slow on first run: If you enabled the Calibre mod, the first startup downloads and installs the full Calibre binary — 3–5 minutes is normal. Don’t kill the container thinking it hung.

What You End Up With

Once this is running, you have a private library that:

  • Works in any browser — no app install required
  • Syncs reading position across devices via OPDS-compatible apps
  • Serves books on your local network at full speed
  • Stores everything in plain files you own completely
  • Costs nothing beyond the server hardware you already have

Setup takes maybe 20 minutes. The OPDS integration with KOReader is what sold me — I read technical documentation on my tablet during commutes and everything stays in one place. Calibre-Web running on a Raspberry Pi 4 idles at under 100MB RAM, so it’s not competing with anything else on your HomeLab.

There’s no good reason to keep your e-book collection scattered across devices and cloud silos. A self-hosted Calibre-Web instance is lightweight, easy to maintain, and gives you full control of your reading library — on your terms.

Share: