Get started
Requirements
Bookplate runs as two Docker containers — the app and its Postgres database. You need:
- Docker with Compose. On a Mac or Windows PC, install Docker Desktop. On Linux, install Docker Engine and the Compose plugin.
- A 64-bit machine — Intel/AMD or ARM, so a Mac, a PC, a Raspberry Pi 4 or 5 (with a 64-bit OS), most NAS boxes, or a cloud server all work.
- About 300 MB of free memory while it runs, and about 750 MB of disk for the two images plus room for your covers and pasted images.
Check Docker is ready with docker compose version. It should print a version number.
Install
Make a folder for Bookplate
This folder holds its two config files. Your library itself lives in Docker volumes.
$ mkdir bookplate && cd bookplateDownload the compose file and the settings template
$ curl -fsSLO https://raw.githubusercontent.com/LeoPhh/bookplate/main/docker-compose.yml$ curl -fsSL https://raw.githubusercontent.com/LeoPhh/bookplate/main/.env.example -o .envFill in your settings
Open
.envin any text editor. Two values are required, and both should be long random strings. Generate them with:# paste this after AUTH_SECRET=$ openssl rand -base64 32# and this after DB_PASSWORD=$ openssl rand -hex 24Then set the address you’ll open Bookplate at. Your finished file looks like this:
AUTH_SECRET=q3F…your first random string…DB_PASSWORD=8c1e…your second random string…PUBLIC_URL=http://localhost:3000BOOKPLATE_PORT=3000REGISTRATION=closedKeep this file private, and keep it with your backups. You never type these values anywhere — they’re not your login.
Start it
The first start downloads the images, which takes a minute or two.
$ docker compose up -dCheck both containers are running — after a few seconds, each should say
healthy:$ docker compose psOpen it
Go to your
PUBLIC_URL—http://localhost:3000if you kept the default — and carry on with the first run.
First run
The first visit shows a Set up your library screen. Enter your name, an email address and a password of at least 8 characters, and choose Create account. This is the account that owns this Bookplate — after it exists, nobody else can sign up.
The email is only your username. Bookplate never sends email, so no confirmation is needed — but using a real address keeps things simple if email features arrive later.
Configuration
All settings live in .env. After changing one, run docker compose up -d to apply it.
| Setting | Default | What it does |
|---|---|---|
AUTH_SECRET | — | Signs your login cookie. Required. Changing it just signs everyone out. |
DB_PASSWORD | — | Password between the app and its database. Required. Set it once and never change it. |
PUBLIC_URL | http://localhost:3000 | The address you open Bookplate at. With https://, sign-in cookies are marked secure. |
BOOKPLATE_PORT | 3000 | The port on the host machine. |
REGISTRATION | closed | closed: only the first account can be created. open: anyone who can reach the server can create their own, separate library. |
BOOKPLATE_VERSION | latest | Pin a release, e.g. 0.2.0 or 0.2. See Updating. |
BOOKPLATE_IMAGE | leophh/bookplate | Set to ghcr.io/leophh/bookplate to pull from GitHub’s registry instead of Docker Hub. |
Bring in an existing library
Go to Settings → Import → Choose a zip… and pick either a Bookplate export (from Export library on any Bookplate) or a zip of the data folder from the original, git-based version of the app.
Books, covers, notes, pasted images and vocabulary all come across. Books and words with the same ids are updated; nothing already in your library is removed, so importing the same file twice is harmless.
Run it
Updating
From your Bookplate folder:
$ docker compose pull$ docker compose up -d
The first command downloads the newest release; the second replaces the app container with it, keeping your data and settings. Database changes are applied automatically when the new version starts. The version you’re on is shown at the bottom of Settings.
To upgrade on your own schedule, pin a version in .env: BOOKPLATE_VERSION=0.2 gets bug fixes for 0.2 but never jumps to 0.3. What changed in each release is listed on GitHub.
Backups and restoring
The easy way: an export
Settings → Export library downloads a zip of your whole library — books, notes, pasted images, covers and vocabulary — as plain JSON, Markdown and image files. Settings → Import reads it back into any Bookplate. It doesn’t include your account, password or profile photo.
A full server backup
This saves everything, every account included. From your Bookplate folder:
$ docker compose exec -T postgres pg_dump -U bookplate bookplate > bookplate-db.sql$ docker compose cp bookplate:/data/uploads ./bookplate-uploads
Keep bookplate-db.sql, the bookplate-uploads folder and your .env together, somewhere other than the same machine.
Restoring a full backup
On a fresh install that uses the same .env, with the backup files in the Bookplate folder, and before starting the app:
$ docker compose up -d --wait postgres$ docker compose exec -T postgres psql -q -U bookplate -d bookplate < bookplate-db.sql$ docker compose run --rm --no-deps --user root -v "$PWD/bookplate-uploads:/backup:ro" bookplate sh -c 'cp -a /backup/. /data/uploads/ && chown -R node:node /data/uploads'$ docker compose up -d
That starts only the database, loads your data into it, copies your images back into place, then starts Bookplate.
Using it from other devices
On your home network
Open http://<your-computer’s-IP>:3000 from a phone or another computer on the same network. On a Mac, the IP is under System Settings → Wi-Fi → Details. Set PUBLIC_URL to that address if you’ll mostly use it from there.
From anywhere, privately
Tailscale (free for personal use) puts your devices on a private network, so you can reach Bookplate from anywhere without exposing it to the internet. Install it on the machine running Bookplate and on your phone, then use the machine’s Tailscale address.
On the public internet
Put Bookplate behind a reverse proxy that provides HTTPS. With Caddy and a domain pointing at your server, this is the whole config:
books.example.com {reverse_proxy localhost:3000}
Then set PUBLIC_URL=https://books.example.com and run docker compose up -d.
Keeping it running
Both containers restart automatically whenever Docker is running — after a crash, or after the machine reboots. On a Mac or PC that means Docker Desktop has to be open: turn on Settings → General → Start Docker Desktop when you sign in. While a laptop sleeps, Bookplate is paused and picks up again on wake.
For a library you can reach at any hour, run it on something that’s always on — a Raspberry Pi, a NAS or a small cloud server.
Useful commands, from your Bookplate folder:
# is it running, and healthy?$ docker compose ps# the app's live logs (Ctrl+C to leave)$ docker compose logs -f bookplate# memory and CPU use$ docker stats# stop it, and start it again$ docker compose stop$ docker compose start
Docker Desktop shows the same under Containers → bookplate, with logs and live stats for each container.
Troubleshooting
- Signing in fails with “Invalid origin”
PUBLIC_URLdoesn’t match the address in your browser — often the case behind a reverse proxy. Make them match, then rundocker compose up -d.- “Port is already allocated” when starting
- Another program uses that port. Change
BOOKPLATE_PORTandPUBLIC_URLas in Install. - The app keeps restarting or shows as unhealthy
- Look at
docker compose logs bookplate. A database connection error almost always meansDB_PASSWORDchanged after the first start — put the original back. - I forgot my password
- There’s no reset yet. If you still have a signed-in browser, change it under Settings → Password — which needs the current one, so keep it in a password manager.
- Book search finds nothing, or covers don’t load
- Search and covers come from Open Library (with iTunes as a fallback for covers), fetched by your server. If your server can’t reach them, add the book by hand and upload or paste a cover instead.
- Something else
- Open an issue on GitHub with what you did, what happened, and the output of
docker compose logs bookplate.
Use it
Adding books
Choose + Add book. Start typing a title or author in the search box: results come from the Open Library catalogue. Picking one fills in the title, author and page count, fetches the cover, and opens it in the cropper.
- Covers can also be uploaded, or pasted from the clipboard with ⌘ V (Ctrl V) anywhere in the dialog. Every cover goes through the cropper, which keeps book proportions, and is compressed before it’s saved.
- No cover? The book gets a cloth-bound cover in one of twelve colours instead.
- Each book also has a genre, a source (book store, Kindle, audiobook, borrowed, second hand, gifted or library), a status (Read, Reading or TBR), whether you own a copy at home, a rating and the date you finished it.
- Everything can be typed in by hand too — the catalogue is optional.
Browsing your library
- Covers shows a wall of covers; Ledger shows a table with status, rating and dates. Both show the most recently finished books first.
- The search box matches titles, authors, genres and notes. The All · Read · Reading · TBR chips filter by status.
- Show notes puts a bookmark ribbon on every book that has notes.
- Click a book to see its details. The pencil icon edits it; Delete removes it along with its notes, pasted images and cover.
Finishing a book
For a book you’re reading, open it and choose Finished Reading. Pick the date you finished and a rating, then Mark as read. It moves to Read and counts towards your statistics.
Notes
Every book has its own notes page — open a book and choose Notes, then Edit. The editor turns Markdown into formatting as you type:
| Type | To get |
|---|---|
#, ##, ### and a space | Headings |
**bold**, *italic*, ~~struck~~, `code` | Inline styles |
- or 1. and a space | Bulleted or numbered list |
> and a space | Quote |
The toolbar does the same, plus links, callout boxes and code blocks. Paste or drop images straight into the text; large ones are downscaled first.
Save keeps your changes; Cancel throws them away, including any images pasted since the last save. Images you delete from a note are cleaned up on the next save.
Vocabulary
The Vocabulary tab keeps the words you learn while reading. Type a word and Bookplate looks it up on Wiktionary, listing each meaning with its part of speech and an example. Add the meaning you were after — or, if the dictionary has nothing, write your own definition.
Tag a word with the book you found it in, and it also appears on that book’s notes page. The list can be searched, sorted and filtered by book.
Statistics
The Statistics tab counts up your reading: books read, read this year, pages turned and average rating, with charts of books per year, ratings, genres and sources.
Everything drills down: click a year, genre, rating or source to see the books behind it, highest rated first, and click any of those books to open it in your library.
Your account
Your profile picture sits in the top-right corner of every page. Click it for Settings and Sign out. In Settings you can:
- Profile — add, crop or remove a profile photo.
- Export and Import your library — see Backups.
- Password — change it. Every other device you’re signed in on is signed out.
- Danger zone — delete your account and everything in it, after confirming your password. This can’t be undone, so export first. If it was the only account, the next visit shows the setup screen again.
Reference
Privacy and your data
- Your library lives only on the machine running Bookplate, in its Postgres database and uploads volume.
- Everything is behind your login — covers and images included.
- Bookplate sends no analytics or telemetry. The only outside services it contacts are Open Library and iTunes (book search and covers) and Wiktionary (definitions), and only when you use those features — through your server, so your browser never talks to them directly. None need an account or API key.
- You can take everything with you at any time with Export library.
FAQ
- Can my family use it too?
- Yes — set
REGISTRATION=open, rundocker compose up -d, and each person creates their own account with a separate library. Anyone who can reach the server can sign up while it’s open, so switch it back toclosedafterwards. - Is there a phone app?
- Bookplate works in your phone’s browser, with tabs along the bottom. Add it to your home screen from the browser’s share menu and it opens like an app.
- Is there a hosted version?
- Not at the moment — Bookplate is self-hosted only, so your library stays yours.
- What does it cost?
- Nothing. Bookplate is open source under the Apache 2.0 license. The code is on GitHub.