Documentation

Run your own Bookplate.

Everything you need to install Bookplate with Docker, keep it running and backed up, and get the most out of it. Written for Bookplate 0.2.

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

  1. Make a folder for Bookplate

    This folder holds its two config files. Your library itself lives in Docker volumes.

    Terminal
    $ mkdir bookplate && cd bookplate
  2. Download the compose file and the settings template

    Terminal
    $ curl -fsSLO https://raw.githubusercontent.com/LeoPhh/bookplate/main/docker-compose.yml
    $ curl -fsSL https://raw.githubusercontent.com/LeoPhh/bookplate/main/.env.example -o .env
  3. Fill in your settings

    Open .env in any text editor. Two values are required, and both should be long random strings. Generate them with:

    Terminal
    # paste this after AUTH_SECRET=
    $ openssl rand -base64 32
    # and this after DB_PASSWORD=
    $ openssl rand -hex 24

    Then set the address you’ll open Bookplate at. Your finished file looks like this:

    .env
    AUTH_SECRET=q3F…your first random string…
    DB_PASSWORD=8c1e…your second random string…
    PUBLIC_URL=http://localhost:3000
    BOOKPLATE_PORT=3000
    REGISTRATION=closed

    Keep this file private, and keep it with your backups. You never type these values anywhere — they’re not your login.

  4. Start it

    The first start downloads the images, which takes a minute or two.

    Terminal
    $ docker compose up -d

    Check both containers are running — after a few seconds, each should say healthy:

    Terminal
    $ docker compose ps
  5. Open it

    Go to your PUBLIC_URL — http://localhost:3000 if 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.

SettingDefaultWhat 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_URLhttp://localhost:3000The address you open Bookplate at. With https://, sign-in cookies are marked secure.
BOOKPLATE_PORT3000The port on the host machine.
REGISTRATIONclosedclosed: only the first account can be created. open: anyone who can reach the server can create their own, separate library.
BOOKPLATE_VERSIONlatestPin a release, e.g. 0.2.0 or 0.2. See Updating.
BOOKPLATE_IMAGEleophh/bookplateSet 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:

Terminal
$ 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:

Terminal
$ 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:

Terminal
$ 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:

Caddyfile
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:

Terminal
# 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_URL doesn’t match the address in your browser — often the case behind a reverse proxy. Make them match, then run docker compose up -d.
“Port is already allocated” when starting
Another program uses that port. Change BOOKPLATE_PORT and PUBLIC_URL as in Install.
The app keeps restarting or shows as unhealthy
Look at docker compose logs bookplate. A database connection error almost always means DB_PASSWORD changed 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:

TypeTo get
#, ##, ### and a spaceHeadings
**bold**, *italic*, ~~struck~~, `code`Inline styles
- or 1. and a spaceBulleted or numbered list
> and a spaceQuote

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, run docker 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 to closed afterwards.
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.