BookLore zu Grimmory migrieren: In-Place-Umzug mit Docker

Grimmory ist der von der Community gepflegte Nachfolger der selbstgehosteten Buch-Bibliothek BookLore. Wer bereits BookLore mit Docker betreibt, kann direkt umziehen, ohne die Bibliothek neu aufzubauen: Grimmory übernimmt die bestehende Datenbank, die App-Daten und die Buchpfade. Diese Anleitung zeigt den In-Place-Umzug Schritt für Schritt – inklusive Backups, vollständiger Compose-Datei und der Stolperfallen, die dabei tatsächlich auftreten.

Für wen ist diese Anleitung? Sie richtet sich an alle, die BookLore bereits mit Docker betreiben und auf Grimmory umziehen möchten. Grundlegende Docker-Kenntnisse (Container, Docker Compose, Volumes) sind hilfreich, aber wir erklären die entscheidenden Begriffe unterwegs. Ein „Fork“ ist dabei einfach eine eigenständige Weiterentwicklung eines Projekts – Grimmory baut also direkt auf BookLore auf.

Warum die In-Place-Migration funktioniert

„In-Place“ bedeutet: Wir bauen nichts neu auf, sondern lassen Grimmory die vorhandenen BookLore-Daten direkt weiterverwenden. Möglich ist das, weil Grimmory ein Fork von BookLore ist und dieselbe Datenbankstruktur als Ausgangspunkt nutzt. Beim ersten Start aktualisiert Grimmory diese Struktur automatisch über Flyway – ein Werkzeug, das die Datenbank Schritt für Schritt auf den neuen Stand bringt, ohne dass du selbst etwas an der Datenbank ändern musst. Das Ergebnis: Alle Bücher, Metadaten, Bibliotheken und Benutzerkonten sind sofort vorhanden, und du meldest dich mit deinem bestehenden BookLore-Account an. Genau das ist auch der vom Projekt empfohlene Migrationsweg.

Wichtigste Regel vorab: BookLore und Grimmory dürfen nicht gleichzeitig laufen. Beide nutzen dieselbe Datenbank, dieselben App-Daten und denselben Port 6060 – ein Parallelbetrieb würde kollidieren und die Daten gefährden.

Voraussetzungen

  • Eine laufende BookLore-Installation mit Docker und MariaDB (die Datenbank, in der BookLore alles speichert).
  • Zugriff auf den Server, auf dem BookLore läuft (z. B. per SSH), und auf die Docker-Compose-Dateien.
  • Dein BookLore-Datenbankpasswort und die verwendeten Pfade.
  • Ausreichend Speicherplatz für die Backups.

Wo finde ich Passwort und Pfade? Beides steht in deiner bestehenden BookLore-Installation: Öffne die aktuelle docker-compose.yml (und ggf. die .env-Datei) deines BookLore-Stacks. Dort findest du das Datenbankpasswort (bei MYSQL_PASSWORD bzw. DATABASE_PASSWORD) und die Verzeichnisse, in denen die Datenbank, die App-Daten und deine Bücher liegen (die Zeilen unter volumes:). Genau diese Werte tragen wir gleich in die Grimmory-Konfiguration ein.

Schritt 1: Backups anlegen

Weil die Migration die echte Datenbank verändert, sichern wir sie zuerst. Ein SQL-Dump plus ein Tarball der App-Daten genügen für einen vollständigen Rückweg:

# 1) Datenbank sichern (alle Tabellen als SQL-Dump)
docker exec mariadb-booklore \
  mariadb-dump -u booklore -p'PLATZHALTER_DB_PASSWORT' booklore \
  > booklore-db-$(date +%F).sql

# 2) App-Daten sichern
tar czf booklore-appdata-$(date +%F).tar.gz /srv/docker/data/booklore

Prüfe kurz, dass der Dump nicht leer ist (Dateigröße > 0) und alle Tabellen enthält. Erst dann geht es weiter.

Schritt 2: BookLore herunterfahren

Damit Grimmory das Datenbank-Verzeichnis exklusiv nutzen kann, muss BookLore vollständig gestoppt werden:

# BookLore stoppen, damit das DB-Datenverzeichnis frei wird
docker compose -f /srv/docker/stacks/booklore/docker-compose.yml down

# Falls ein alter/kaputter Grimmory-Versuch laeuft: ebenfalls stoppen
docker compose -f /srv/docker/stacks/grimmory/docker-compose.yml down

Schritt 3: Grimmory-Stack konfigurieren

Jetzt legen wir die docker-compose.yml für Grimmory an – am besten in einem eigenen Ordner, z. B. /srv/docker/stacks/grimmory/. Der Clou: Der Datenbank-Container bindet das bestehende BookLore-Datenverzeichnis ein, und Grimmory zeigt auf die vorhandene Datenbank booklore. Kopiere die folgende Datei und passe die markierten Stellen an:

services:
  grimmory:
    image: ghcr.io/grimmory-tools/grimmory:latest
    container_name: grimmory
    ports:
      - "6060:6060"
    environment:
      USER_ID: 1000
      GROUP_ID: 1000
      TZ: Europe/Berlin
      # WICHTIG: die BESTEHENDE BookLore-Datenbank weiterverwenden (heisst "booklore")
      DATABASE_URL: jdbc:mariadb://mariadb-grimmory:3306/booklore
      DATABASE_USERNAME: booklore
      DATABASE_PASSWORD: PLATZHALTER_DB_PASSWORT
      # ohne diese Zeile startet Grimmory bei lokalem Speicher nicht sauber
      DISK_TYPE: LOCAL
      SWAGGER_ENABLED: "false"
      FORCE_DISABLE_OIDC: "false"
    volumes:
      - /srv/docker/data/booklore/app:/app/data     # bestehende BookLore-App-Daten
      - /srv/docker/mnt/ebooks:/books               # Buchpfad aus BookLore uebernehmen
      - /srv/docker/mnt/ebooks:/bookdrop
    depends_on:
      mariadb-grimmory:
        condition: service_healthy
    restart: unless-stopped

  mariadb-grimmory:
    image: lscr.io/linuxserver/mariadb:11.4.8
    container_name: mariadb-grimmory
    environment:
      PUID: 1000
      PGID: 1000
      TZ: Europe/Berlin
      MYSQL_ROOT_PASSWORD: PLATZHALTER_ROOT_PASSWORT
      # bestehende BookLore-DB und -Nutzer weiterverwenden
      MYSQL_DATABASE: booklore
      MYSQL_USER: booklore
      MYSQL_PASSWORD: PLATZHALTER_DB_PASSWORT
    volumes:
      # HIER liegt die bestehende BookLore-Datenbank -> Grimmory uebernimmt sie
      - /srv/docker/data/booklore/mariadb/config:/config
    healthcheck:
      test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 10
    restart: unless-stopped

Diese Stellen musst du anpassen (die restlichen Werte kannst du übernehmen):

  • PLATZHALTER_DB_PASSWORT und PLATZHALTER_ROOT_PASSWORT → deine echten Datenbankpasswörter aus der alten BookLore-Konfiguration. Das DB-Passwort muss an allen drei Stellen identisch sein.
  • Die Pfade links vom Doppelpunkt unter volumes: → die Verzeichnisse deiner bestehenden BookLore-Installation (DB-Daten, App-Daten, Bücher-Ordner).
  • Europe/Berlin → deine Zeitzone, falls abweichend.

Zwei Begriffe zum Verständnis: Ein Volume in der Form /pfad/auf/dem/server:/pfad/im/container hängt einen Ordner deines Servers in den Container ein (ein „Bind-Mount“). Deshalb sieht Grimmory die alten Daten. Und der Name mariadb-grimmory hinter DATABASE_URL ist der Service-Name des Datenbank-Containers – über diesen internen Namen finden sich die beiden Container im selben Compose-Stack. Wichtig: Der :/config-Mount muss exakt auf das Verzeichnis zeigen, in dem die bisherigen BookLore-Datenbankdaten liegen – sonst startet Grimmory mit einer leeren Datenbank.

Schritt 4: Starten und die Migration beobachten

Jetzt den Stack hochfahren und den Log mitlesen. Grimmory wartet, bis MariaDB „healthy“ meldet, und führt dann die Flyway-Migration aus:

docker compose -f /srv/docker/stacks/grimmory/docker-compose.yml up -d

# Start live mitverfolgen (Flyway-Migration + App-Start)
docker compose -f /srv/docker/stacks/grimmory/docker-compose.yml logs -f grimmory

Im Log solltest du sehen, wie Flyway die Migrationen anwendet (im getesteten Fall 47 Migrationen bis Schema-Version 146) und anschließend Tomcat auf Port 6060 startet. Meldungen wie „Successfully applied … migrations“ und ein laufender Webserver sind das Zeichen für den Erfolg.

Schritt 5: Verifizieren

# Container-Status (beide sollten "healthy" sein)
docker ps --filter name=grimmory

# Erreichbarkeit pruefen (erwartet HTTP 200)
curl -I http://<SERVER-IP>:6060

Ruf anschließend http://<SERVER-IP>:6060 im Browser auf und melde dich mit deinem bestehenden BookLore-Konto an. Deine Bibliotheken und Bücher müssen vollständig vorhanden sein – im Testlauf waren es 144 Bücher, 8 Bibliotheken und der migrierte Benutzer. Läuft alles, ist der Umzug abgeschlossen.

Nachbereitung

  • Reverse Proxy: War BookLore z. B. in Zoraxy, Nginx Proxy Manager oder Traefik als Ziel hinterlegt, zeigt der Eintrag dank identischem Port 6060 automatisch auf Grimmory – hier ist meist keine Änderung nötig.
  • BookLore-Stack deaktiviert lassen: Starte den alten BookLore-Container nicht erneut. Die Original-Dateien bleiben aber liegen, ein Rollback ist möglich.
  • Passwörter rotieren (optional): Die Datenbankpasswörter stehen wie zuvor im Klartext in der .env/Compose-Datei. Ein guter Zeitpunkt, sie im Zuge des Umzugs zu erneuern.

Häufige Stolperfallen

„UnknownHostException“ beim Start: Der häufigste Fehler. Grimmory kann den Datenbank-Host nicht auflösen, weil die DATABASE_URL auf einen Container in einem anderen Compose-Projekt/Netzwerk zeigt (z. B. noch auf den alten mariadb-booklore). Lösung: Datenbank und App im selben Compose-Stack definieren und die DATABASE_URL auf den dortigen Service-Namen setzen.

Grimmory startet, findet aber keine Bücher/DB: Dann zeigt der :/config-Mount nicht auf das bestehende BookLore-Datenverzeichnis, oder DATABASE_URL nennt die falsche Datenbank. Prüfe Pfad und Datenbanknamen (booklore).

Fehler wegen Speichertyp: Fehlt DISK_TYPE=LOCAL, kann Grimmory bei lokalem Speicher den Start verweigern. Die Zeile gehört in die Umgebungsvariablen des App-Containers.

Port 6060 belegt: Läuft BookLore noch, ist der Port blockiert. Stelle sicher, dass der alte Stack mit docker compose down gestoppt ist.

Rollback zu BookLore

Da die Migration das Schema in-place auf Version 146 angehoben hat, ist ein sauberer Rückweg über das Datenbank-Backup vorgesehen: Grimmory stoppen, das in Schritt 1 erstellte SQL-Backup in die Datenbank zurückspielen und anschließend den alten BookLore-Stack wieder starten. Deshalb ist der Dump aus Schritt 1 so wichtig – ohne ihn lässt sich das bereits migrierte Schema nicht ohne Weiteres wieder auf BookLore zurückführen.

Häufige Fragen (FAQ)

Bleiben meine Bücher und Metadaten erhalten?

Ja. Grimmory übernimmt die bestehende BookLore-Datenbank und die App-Daten vollständig. Bibliotheken, Metadaten und Lesefortschritt sind nach dem Umzug sofort vorhanden.

Muss ich meine Benutzer neu anlegen?

Nein. Die Benutzerkonten werden mitmigriert – du meldest dich mit deinem bestehenden BookLore-Login an.

Kann ich BookLore und Grimmory parallel testen?

Nein. Beide nutzen dieselbe Datenbank, dieselben Daten und denselben Port. Für einen gefahrlosen Test müsstest du eine Kopie der Datenbank auf einem anderen Port aufsetzen – ein Parallelbetrieb auf denselben Daten ist ausgeschlossen.

Warum ein Community-Fork?

Grimmory führt BookLore als Community-Projekt weiter und bringt Funktionen wie intelligente Regale, Metadaten-Abgleich, Kobo/KOReader-Sync, OPDS-Unterstützung und einen eingebauten Reader mit. Wer BookLore nutzt, bekommt den vertrauten Funktionsumfang plus aktive Weiterentwicklung.


Quellen: Grimmory auf GitHub, offizielle docker-compose.yml.

Nach oben scrollen