$linuxjunkies
>

Self-Host Calibre-Web for Your eBook Library

Deploy Calibre-Web with Docker, import your Calibre library, configure send-to-Kindle email delivery, and set up an OPDS catalog for KOReader.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Docker Engine and Docker Compose plugin installed and working
  • A non-root user with membership in the docker group
  • An existing Calibre library folder (containing metadata.db) or Calibre desktop to create one
  • A dedicated email address with SMTP access (and an App Password if using Gmail) for Send-to-Kindle

Calibre-Web gives you a polished browser interface over a standard Calibre library, with user management, OPDS support for e-readers like KOReader, and a send-to-Kindle pipeline. Running it in Docker keeps dependencies clean and makes upgrades trivial. This guide walks through a production-ready deployment: persistent storage, reverse proxy headers, library import, Kindle delivery, and OPDS configuration.

Prerequisites and Directory Layout

You need Docker and Docker Compose installed, a non-root user in the docker group, and an existing Calibre library directory (the folder containing metadata.db). If you are starting fresh, Calibre desktop can create an empty library that Calibre-Web can then manage.

Create a clean directory structure before writing any config:

mkdir -p ~/calibre-web/{config,books}
# If you already have a library, note its absolute path — do NOT copy it yet

Docker Compose File

The linuxserver/calibre-web image is the most actively maintained option. It bakes in the optional Calibre binaries needed for format conversion and send-to-Kindle.

cat > ~/calibre-web/docker-compose.yml << 'EOF'
services:
  calibre-web:
    image: lscr.io/linuxserver/calibre-web:latest
    container_name: calibre-web
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - DOCKER_MODS=linuxserver/mods:universal-calibre   # adds full Calibre binaries
    volumes:
      - ./config:/config
      - /path/to/your/calibre/library:/books
    ports:
      - "8083:8083"
    restart: unless-stopped
EOF

Replace /path/to/your/calibre/library with the real absolute path. Replace PUID/PGID with the output of id -u and id -g for your user — this prevents permission mismatches on the mounted volumes.

Starting the Container

cd ~/calibre-web
docker compose up -d
docker compose logs -f calibre-web

The first start pulls the image and, if you included the Calibre mod, downloads the Calibre AppImage — allow 2–5 minutes. You will see Server starting... in the logs when it is ready. Press Ctrl-C to detach from logs; the container keeps running.

Initial Web Setup

Open http://<server-ip>:8083 in a browser. Default credentials are admin / admin123.

  1. On the first-run wizard, set the Location of Calibre database to /books — the container path, not the host path.
  2. Click Save. Calibre-Web reads metadata.db and populates the library immediately.
  3. Go to Admin → Edit Profile and change the admin password before doing anything else.

Importing Your Calibre Library

Calibre-Web does not duplicate your files; it reads the same metadata.db that Calibre desktop uses. The import is the volume mount you already set up. A few important rules:

  • Do not run Calibre desktop and allow Calibre-Web to write to the library simultaneously — they will corrupt metadata.db. Choose one active writer at a time, or enable Calibre's built-in Content Server as the write path and point Calibre-Web at a read-only copy.
  • To add books through the web interface, go to Admin → Edit Basic Configuration → Feature Configuration and enable Allow Upload. Uploaded files are placed into the library folder and registered in metadata.db.
  • Cover images are served from the library's existing cover files; no extra configuration is required.

Configuring Send-to-Kindle

Calibre-Web can email books directly to a Kindle address using Amazon's Send-to-Kindle delivery. The universal-calibre Docker mod is required for format conversion (e.g., EPUB → MOBI/AZW3).

Step 1 — Create a sending email account

Use a dedicated Gmail or SMTP account. For Gmail, create an App Password under your Google Account security settings (requires 2-Step Verification). Do not use your main account password.

Step 2 — Configure SMTP in Calibre-Web

Go to Admin → Edit Basic Configuration → E-mail Server Settings and fill in:

  • SMTP Hostname: smtp.gmail.com
  • SMTP Port: 587
  • Encryption: STARTTLS
  • SMTP Login / Password: your sending address and App Password
  • From e-mail: the same sending address

Step 3 — Approve the sender address on Amazon

Log in to Amazon's Manage Your Content and Devices, go to Preferences → Personal Document Settings, and add your sending address to the Approved Personal Document E-mail List. Also note your Kindle delivery address (e.g., [email protected]).

Step 4 — Set the Kindle address per user

Each user sets their own Kindle address under Admin → Manage Users → (edit user) → Kindle E-mail. Once set, any book page shows a Send to Kindle button that triggers conversion and delivery.

Enabling OPDS for KOReader

OPDS (Open Publication Distribution System) exposes your library as a catalog feed that apps like KOReader, Lithium, and Moon+ Reader can browse and download from directly.

Enable OPDS in Calibre-Web

Go to Admin → Edit Basic Configuration → Feature Configuration and toggle Enable OPDS Catalog on. Save.

Connect KOReader

  1. In KOReader, open the top menu and go to Search → OPDS Catalog.
  2. Tap the + icon to add a catalog. Set the URL to:
    http://<server-ip>:8083/opds
  3. Enter your Calibre-Web username and password when prompted.
  4. Browse, download, and open books directly — KOReader remembers reading progress on device.

If Calibre-Web sits behind a reverse proxy with HTTPS (strongly recommended for any non-LAN access), use https:// and your domain instead. Make sure the proxy passes X-Forwarded-Proto and X-Forwarded-For headers; the linuxserver image respects these out of the box.

Putting Calibre-Web Behind a Reverse Proxy

Exposing port 8083 directly is fine on a LAN. For external access, put it behind Caddy or nginx with TLS. A minimal Caddy block:

cat /etc/caddy/Caddyfile
# books.example.com {
#     reverse_proxy localhost:8083
# }

Caddy handles TLS via Let's Encrypt automatically. For nginx, ensure you pass the necessary headers:

location / {
    proxy_pass         http://127.0.0.1:8083;
    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;
}

Upgrading

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

Configuration and library data live in the mounted volumes, so upgrades are non-destructive. Check the release notes before major version jumps.

Verification

  • Library loads: browse to http://<server-ip>:8083 and confirm books appear with covers.
  • OPDS works: curl the feed — you should get an Atom XML response: curl -u admin:yourpassword http://<server-ip>:8083/opds
  • Send-to-Kindle: click Send to Kindle on any book and watch Admin → Task List for a successful conversion and send job.
  • Container restarts cleanly: docker compose restart calibre-web && docker compose ps — status should read Up.

Troubleshooting

"No books found" after library path is set

Confirm the container path (/books) actually contains metadata.db at the root level, not inside a subdirectory. Run docker exec calibre-web ls /books to verify. Also check that PUID/PGID match the file owner on the host with ls -ln /path/to/library.

Send-to-Kindle job fails with conversion error

The universal-calibre mod must be present. Confirm with docker exec calibre-web which ebook-convert. If it returns nothing, remove the container (docker compose down), verify the DOCKER_MODS env line is in your compose file, and bring it back up. First start will re-download the mod.

OPDS returns 401 even with correct credentials

Some OPDS clients send credentials only after receiving a 401 challenge. This is normal. If it loops, check that the user account has the Allow OPDS Access permission enabled under Admin → Manage Users.

Permission denied writing to /books

The container user (PUID/PGID) does not have write access to the host directory. On the host, run sudo chown -R 1000:1000 /path/to/library, adjusting the UID/GID to match your values. Restart the container afterward.

tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

Can I use my existing Calibre desktop library without copying files?
Yes. Calibre-Web reads the same metadata.db that Calibre desktop writes. Just mount the existing library directory into the container at /books. Avoid running both Calibre desktop and Calibre-Web in write mode against the same database simultaneously to prevent corruption.
Why do I need the universal-calibre Docker mod?
The base Calibre-Web image only ships the Python web app. The mod adds the full Calibre suite (including ebook-convert), which is required for on-the-fly format conversion — for example, converting EPUB to AZW3 before sending to a Kindle address.
Does OPDS support search and filtering in KOReader?
Yes. Calibre-Web's OPDS endpoint supports browsing by title, author, series, tags, and shelves, and responds to OpenSearch queries. KOReader can search the catalog directly from the OPDS browser pane.
How do I restrict users to only certain books or shelves?
Calibre-Web has per-user permission flags including download, upload, edit, and admin rights, plus the ability to restrict a user to a specific virtual library (defined by a Calibre search expression) via Admin → Manage Users.
Is it safe to expose Calibre-Web directly to the internet?
Not on plain HTTP and not without changing the default password. At minimum, put it behind a TLS-terminating reverse proxy and use a strong password. For higher security, add HTTP Basic Auth at the proxy level or restrict access to a VPN, since Calibre-Web's session handling is not hardened for adversarial exposure.

Related guides