# 05-booklore.md

kstack:
  book: Centerpoint Home Lab
  chapter: Documents & Organization
  page: Booklore
  tags: [booklore, books, library, mariadb, step-ca]
---

## Overview

Booklore is a personal e-book library manager. It indexes books from the NFS
Multimedia share (read-only) and a local bookdrop directory for new additions.
The app is a Java/Spring Boot application (JDK 25 with Shenandoah GC) backed by
MariaDB. It uses its own internal authentication — no Authentik ForwardAuth or
OIDC. The Step-CA root certificate is bind-mounted into the system trust store
to allow Booklore to make HTTPS calls to internal `*.home.local` services.

## Access

| Type     | URL                                      | Auth                              |
|----------|------------------------------------------|-----------------------------------|
| External | `https://booklore.jeevesconsults.ca`     | GeoBlock + CrowdSec (own auth)    |
| Internal | `https://booklore.home.local`            | Own auth (Step-CA TLS)            |

## Containers

| Container    | Image                            | Role             |
|--------------|----------------------------------|------------------|
| `booklore`   | `grimmory/grimmory:latest`       | Web application  |
| `booklore-db`| `lscr.io/linuxserver/mariadb:latest` | MariaDB database |

### booklore (application)

**Key environment variables:**

| Variable            | Value / Notes                                     |
|---------------------|---------------------------------------------------|
| `DATABASE_USERNAME` | `booklore`                                        |
| `DATABASE_PASSWORD` | **REDACTED**                                      |
| `DATABASE_URL`      | `jdbc:mariadb://booklore-db:3306/booklore`        |
| `BOOKLORE_PORT`     | `6060`                                            |
| `DISK_TYPE`         | `NETWORK` (books from NFS mount)                  |
| `USER_ID` / `GROUP_ID` | `1000`                                         |
| `TZ`                | `America/Toronto`                                 |
| `APP_VERSION`       | `v3.2.0`                                          |

**Runtime:** Java 25 (Temurin JDK 25.0.3) with Shenandoah GC.  
JVM tuning: max 60% RAM, Shenandoah compact heuristics, 256MB metaspace cap.

**Bind mounts:**

| Host Path                                                   | Container Path                                  | Purpose                   |
|-------------------------------------------------------------|-------------------------------------------------|---------------------------|
| `/mnt/Multimedia/Books`                                     | `/books`                                        | Book library (read-only via NFS) |
| `/home/jeeves/docker/booklore/data`                         | `/app/data`                                     | App state and metadata    |
| `/home/jeeves/docker/booklore/bookdrop`                     | `/bookdrop`                                     | Drop zone for new books   |
| `/home/jeeves/docker/step-ca/config/certs/root_ca.crt`     | `/usr/local/share/ca-certificates/step-ca.crt` | Step-CA root trust injection |

### booklore-db (MariaDB LSIO)

**Image:** `lscr.io/linuxserver/mariadb:latest`

| Variable       | Value      |
|----------------|------------|
| `MYSQL_DATABASE` | `booklore` |
| `MYSQL_USER`   | `booklore` |
| `MYSQL_PASSWORD` | **REDACTED** |
| `PUID` / `PGID`| `1000`     |

**Bind mounts:**

| Host Path                              | Container Path |
|----------------------------------------|----------------|
| `/home/jeeves/docker/booklore/mariadb` | `/config`      |

## Traefik Labels

```yaml
traefik.http.routers.booklore-external.rule: Host(`booklore.jeevesconsults.ca`)
traefik.http.routers.booklore-external.entrypoints: websecure
traefik.http.routers.booklore-external.tls.certresolver: letsencrypt
traefik.http.routers.booklore-external.middlewares: plex-geoblock@file,crowdsec-bouncer@file
traefik.http.routers.booklore-external.service: booklore-svc

traefik.http.routers.booklore-internal.rule: Host(`booklore.home.local`)
traefik.http.routers.booklore-internal.entrypoints: websecure
traefik.http.routers.booklore-internal.tls.certresolver: step-ca
traefik.http.routers.booklore-internal.service: booklore-svc

traefik.http.services.booklore-svc.loadbalancer.server.port: 6060
```

## Notes / Gotchas

- The Step-CA root certificate bind mount (`root_ca.crt` → `/usr/local/share/ca-certificates/`) makes the container's Java runtime trust internal TLS certificates. This is required if Booklore makes any HTTPS requests to `*.home.local` services.
- `/mnt/Multimedia/Books` is the NFS share from UnRAID — it must be mounted before
  Booklore starts or the library scan will fail silently. Check `df -h /mnt/Multimedia`
  if the library appears empty.
- Drop new e-books (EPUB, PDF) into `/home/jeeves/docker/booklore/bookdrop` for
  automatic library import.
- `grimmory/grimmory:latest` is the container image name for the Booklore project.

---
*Last Updated: 2026-06-17*