Skip to content

dubyte/dir2opds

Repository files navigation

dir2opds

Go Reference License: GPL v3 Releases

Serve an OPDS 1.1–compliant book catalog from a directory. No database, no Calibre—just point dir2opds at a folder and use any OPDS client to browse and download your books.


Table of contents


What is OPDS?

OPDS (Open Publication Distribution System) is a standard for cataloging and distributing digital publications. OPDS clients (ebook readers, apps) can discover, browse, and download books from an OPDS server. dir2opds turns a plain directory tree into such a server.

Features

  • OPDS 1.1 compliant — Works with standard ebook readers and OPDS clients
  • No database — Reads directly from your filesystem; no Calibre or extra setup
  • Flexible layout — Organize by folders; optional metadata from EPUB/PDF
  • Search — Optional filename search (OpenSearch)
  • Covers — Optional cover.jpg / folder.jpg as catalog covers
  • Multiple formats — EPUB, PDF, MOBI, AZW3, and more via configurable MIME types
  • Lightweight — Single binary; suitable for headless servers and containers

Quick start

Using Docker (replace v1.6.0 with the latest release if desired):

docker run -d -p 8080:8080 -v ./books:/books --name dir2opds ghcr.io/dubyte/dir2opds:v1.6.0

Then open http://localhost:8080 in an OPDS client or browser.

Using Go:

go install github.com/dubyte/dir2opds@latest
dir2opds -dir /path/to/books -port 8080

Tip: For best client compatibility, use folders that contain either only subfolders (navigation) or only book files (acquisition), not mixed.


Installation

Choose one of the following.

Go install

go install github.com/dubyte/dir2opds@latest

Pre-built binaries

Download binaries for Linux, macOS, Windows, and other platforms from the Releases page.

Docker

docker pull ghcr.io/dubyte/dir2opds:v1.6.0
docker run \
  -d \
  -m 256MB \
  --restart always \
  -p 8080:8080 \
  -v ./books:/books \
  --name dir2opds \
  ghcr.io/dubyte/dir2opds:v1.6.0

Use a specific release tag instead of v1.6.0 if needed. Thanks to rockavoldy for the run example.

Podman

Pre-built image:

podman pull ghcr.io/dubyte/dir2opds:v1.6.0

Build from source:

podman build -t localhost/dir2opds .

Run (OPDS on port 8080):

podman run \
  -d \
  -m 256MB \
  --restart always \
  -p 8080:8080 \
  -v ./books:/books \
  --name dir2opds \
  ghcr.io/dubyte/dir2opds:v1.6.0

Rootless (e.g. non-root user, SELinux): use a bind mount with the Z option and keep the user namespace:

mkdir -p /data/Books
podman run \
  -d \
  -m 256MB \
  --restart always \
  --userns=keep-id \
  -p 8080:8080 \
  -v /data/Books:/books:Z \
  --name dir2opds \
  ghcr.io/dubyte/dir2opds:v1.6.0

Add -debug for request logging, e.g. ... ghcr.io/dubyte/dir2opds:v1.6.0 /dir2opds -debug.

Raspberry Pi (binary + systemd)

cd && mkdir dir2opds && cd dir2opds
# Replace v1.6.0 and the asset name with the release that matches your system
wget https://github.com/dubyte/dir2opds/releases/download/v1.6.0/dir2opds_1.6.0_linux_armv7.tar.gz
tar xvf dir2opds_1.6.0_linux_armv7.tar.gz

sudo nano /etc/systemd/system/dir2opds.service
# Paste the unit below, then set the full path of your books folder in -dir

sudo systemctl enable --now dir2opds.service

/etc/systemd/system/dir2opds.service:

[Unit]
Description=dir2opds
Documentation=https://github.com/dubyte/dir2opds
After=network-online.target

[Service]
User=pi
Restart=on-failure
ExecStart=/home/pi/dir2opds/dir2opds -dir <FULL_PATH_TO_BOOKS> -port 8080

[Install]
WantedBy=multi-user.target

Other platforms

Installation scripts and configs for FreeBSD, Illumos, and Linux are in the files/ directory.

Build from source

Requires Go 1.21+. Build for multiple platforms:

make build-all

Binaries are written to bin/.


Usage

Default: serve ./books on http://0.0.0.0:8080.

dir2opds -dir /path/to/books -port 8080

Options

Flag Description
-calibre Hide files stored by Calibre
-debug Log requests
-dir Directory with books (default: ./books)
-extract-metadata Extract title/author from EPUB and PDF
-hide-dot-files Hide files whose names start with a dot
-host Listen address (default: 0.0.0.0)
-mime-map Custom MIME types, e.g. .mobi:application/x-mobipocket-ebook,.azw3:application/vnd.amazon.ebook
-no-cache Add response headers to disable client caching
-port Listen port (default: 8080)
-search Enable basic filename search
-show-covers Use cover.jpg or folder.jpg as catalog covers
-sort Sort entries: name, date, or size (default: name)

Compatible clients

These OPDS clients have been tested with dir2opds:

Client Platform Notes
Moon+ Reader Android Tested
Cantook iPhone Tested
KYBook 3 iOS Enable Settings → Apps → KyBook 3 → Local Network. Older app may not show the prompt; enable manually.

Documentation


Contributing

Contributions are welcome. Please read CONTRIBUTING.md for license agreements, development setup, and pull request process.


License

This project is licensed under the GNU General Public License v3.0. See LICENSE for the full text.


Acknowledgments

  • @clach04 — Testing and reporting missing content type for comics.
  • @masked-owl — Reporting the HTTP path traversal security issue.
  • @mufeedali — Update to push image to ghcr.io.
  • @kulak — Add podman support.
  • @thenktor - init files and Makefile improvements.
  • @rockavoldy — For the docker command example.

About

Serve an OPDS based on a directory

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors