Deploy Booklore | (Just Updated) Ebook Library With REST API, Admin Generated at Boot

Booklore ebook library + MariaDB, OPDS, Kobo sync, REST API, admin set

Deploy Booklore | (Just Updated) Ebook Library With REST API, Admin Generated at Boot

Just deployed

/data

Just deployed

/var/lib/mysql

Deploy and Host Booklore on Railway

Booklore is a self-hosted ebook and comic library with multi-user accounts, smart shelves, automatic metadata, a built-in EPUB/PDF/CBZ reader, OPDS and Kobo/KOReader sync, and a REST API. This template deploys Booklore with its own MariaDB database, a persistent volume, and an admin account generated at deploy time - nothing to fill in, no setup wizard to click through.

Easy for an LLM agent to use. Deploy, read the variables below, log in over the REST API and call it. The first admin user is created by the start command the moment the API answers, so the public setup endpoint is never left open to a stranger.

About Hosting Booklore

Two services run in one Railway project:

  • booklore - the official ghcr.io/booklore-app/booklore image (pinned by digest). One volume mounted at /data holds the app config and thumbnails (/app/data), the library folder (/books) and the BookDrop import folder (/bookdrop); the start command links those three paths into the volume.
  • mariadb - the official mariadb image (pinned by digest) on its own volume. The data directory is a subfolder of the mount, so the filesystem's lost+found never lands inside it. The database password is generated and wired into Booklore over the private network.

On first boot the start command waits for MariaDB, lets Booklore run its migrations, then calls the setup endpoint once to create the admin user with the generated password. On every later boot setup is already complete and nothing changes, so redeploys are safe. Booklore is a JVM app and idles at about 1 GB of memory.

Agent contract

  • Public URL: https://RAILWAY_PUBLIC_DOMAIN (the service domain)
  • Private URL: http://booklore.railway.internal:8080 (database: mariadb.railway.internal:3306, user and database booklore)
  • Credentials: username admin (fixed), email in BOOKLORE_ADMIN_EMAIL, password in BOOKLORE_ADMIN_PASSWORD
  • Auth: POST /api/v1/auth/login with JSON {"username","password"} returns accessToken (JWT); send it as Authorization: Bearer ACCESS_TOKEN
  • Write path: a request with no token is refused, write without key: 403 (and read without key: 403)
  • Health: GET / returns 200; GET /api/v1/setup/status returns "data":true once the admin exists
BASE=https://YOUR-DOMAIN.up.railway.app
TOKEN=$(curl -s "$BASE/api/v1/auth/login" -H 'content-type: application/json' \
  -d "{\"username\":\"admin\",\"password\":\"$BOOKLORE_ADMIN_PASSWORD\"}" | sed -n 's/.*"accessToken":"\([^"]*\)".*/\1/p')
curl -s "$BASE/api/v1/setup/status"                       # {"data":true,...}
curl -s "$BASE/api/v1/libraries" -H "Authorization: Bearer $TOKEN"          # []
curl -s -X POST "$BASE/api/v1/libraries" -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"name":"Main","icon":"book","iconType":"PRIME_NG","watch":false,"paths":[{"path":"/books"}]}'
curl -s -o /dev/null -w "read without key: %{http_code}\n" "$BASE/api/v1/libraries"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST "$BASE/api/v1/libraries" \
  -H 'content-type: application/json' -d '{"name":"x","paths":[{"path":"/books"}]}'
# expect: write without key: 403

Why Deploy Booklore on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Booklore on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

  • No setup wizard - the admin account exists as soon as the service is healthy, with a generated password in your variables.
  • Setup endpoint closed at boot - the first-user endpoint is public until an admin exists, so the start command creates the admin within seconds of the API starting, before Railway routes traffic to it.
  • Zero configuration - no variable asks you for anything; the database is wired over the private network.
  • Data survives redeploys - the library, covers, accounts and database each sit on a volume, verified with a write, a redeploy and a read.

Common Use Cases

  • Personal ebook and comic library - upload EPUB, PDF and CBZ files and read them in the browser on any device.
  • E-reader sync server - OPDS for reading apps, plus Kobo and KOReader progress sync.
  • Agent-managed library - let an LLM agent create libraries and manage books through the REST API.

Dependencies for Booklore Hosting

  • A volume at /data on the booklore service and a volume at /var/lib/mysql on the mariadb service (both included in this template).

Deployment Dependencies


Template Content

More templates in this category

View Template
RustFS | (Just Updated) S3 Object Store, Public URL and Keys Set
S3-compatible object store, keys and public URL preset, volume kept

SuperSlowSloth
0
View Template
TimescaleDB
A PostgreSQL-based time-series database for analytics on Railway.

Rakit
1
View Template
NEW
Neo4j 2026.10 Community
Neo4j graph database with APOC, Browser, Bolt TCP proxy and a volume

My Projects
0