Deploy Booklore | (Just Updated) Ebook Library With REST API, Admin Generated at Boot
Booklore ebook library + MariaDB, OPDS, Kobo sync, REST API, admin set
booklore
Just deployed
/data
mariadb
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/bookloreimage (pinned by digest). One volume mounted at/dataholds 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
mariadbimage (pinned by digest) on its own volume. The data directory is a subfolder of the mount, so the filesystem'slost+foundnever 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 databasebooklore) - Credentials: username
admin(fixed), email inBOOKLORE_ADMIN_EMAIL, password inBOOKLORE_ADMIN_PASSWORD - Auth:
POST /api/v1/auth/loginwith JSON{"username","password"}returnsaccessToken(JWT); send it asAuthorization: Bearer ACCESS_TOKEN - Write path: a request with no token is refused,
write without key: 403(andread without key: 403) - Health:
GET /returns 200;GET /api/v1/setup/statusreturns"data":trueonce 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
/dataon thebookloreservice and a volume at/var/lib/mysqlon themariadbservice (both included in this template).
Deployment Dependencies
- booklore-app/booklore - upstream project
- Booklore documentation - setup and features
- mariadb on Docker Hub - the database image
Template Content
mariadb
mariadb:11.8