Sign inSign up

gcorbaz/mybibli

By gcorbaz

β€’Updated 10 days ago

Self-hosted personal library catalog β€” Rust + Axum + MariaDB. Single-tenant, single household, run

Image
0

4.9K

gcorbaz/mybibli repository overview

mybibli

⁠mybibli

Self-hosted personal library catalog β€” Rust + Axum + MariaDB. Single-tenant, single household, runs on your NAS.

GitHub Β· Roadmap Β· License: AGPL v3+

β πŸ›‘ Install 1.1.0 or later β€” required

Tags below 1.1.0 (v1.0.0 … v1.0.5) shipped with a hard-coded admin/admin seed. Anyone reaching that container's URL gained admin. Every pre-1.1.0 tag has been removed from Docker Hub to prevent accidental installs. Fresh installs at 1.1.0+ greet you with the first-launch setup wizard (you create the admin account, the seed is gated out).

If you ran a pre-1.1.0 build, wipe the database before pulling 1.1.0+. See the install warning⁠ for the full writeup.

⁠⚠️ Built for a local network, not for the open internet

mybibli is designed for one household on one LAN. Login attempts are not rate-limited, there is no second authentication factor, the session cookie carries no Secure attribute unless you set MYBIBLI_COOKIE_SECURE=true, and the catalogue is readable without signing in β€” a feature, not an oversight.

Do not forward a port to it. To reach your library from outside the house, use a private tunnel (Tailscale, WireGuard, your router's VPN), or put it behind a TLS reverse proxy and set MYBIBLI_COOKIE_SECURE=true. The reasoning is in docs/auth-threat-model.md⁠; report anything that contradicts it via SECURITY.md⁠.

⁠What it is

  • Barcode-first cataloging. Scan ISBN / EAN-13 β†’ metadata resolves asynchronously through a provider chain (BDGest β†’ BnF β†’ Google Books β†’ Library of Congress β†’ K10plus β†’ Open Library β†’ MusicBrainz β†’ OMDb β†’ TMDb) with cover-image download and similar-title detection.
  • Multi-media. Books, BD/comics with multi-position omnibus volumes, audio, films/series β€” each typed correctly with the right provider chosen automatically.
  • Series + collection awareness. Gap detection on series volumes, Dewey-based browsing, similar-titles section.
  • Management labels. An admin defines a vocabulary once ("To check", "Re-read", "Damaged binding"); a librarian applies any of it to titles and to individual copies from that one shared list, and a /labels page lists the vocabulary with its counts and drills down to what carries each label. Internal to the library β€” an anonymous visitor sees none of it.
  • Storage-location tracking. Configurable hierarchy (room β†’ shelf β†’ row β†’ …), barcode-on-shelf workflow, per-location volume list, optional organizational containers (folders, not shelves), shelf-audit workflow ("Γ€ contrΓ΄ler") with home-dashboard indicator.
  • Loan management. Borrower CRUD, loan registration with automatic location restoration on return, overdue threshold (admin-configurable), per-borrower history.
  • Wishlist + valuation. First-class /wishlist with provider-chain ISBN preview + free-form add, mark-as-bought, server-rendered PDF export. Optional per-volume purchase_price + current_value with per-currency totals and a /stats/value page (default OFF, admin opt-in).
  • JSON HTTP API. /api/v1/* with API-key auth (argon2-hashed, Authorization: Bearer or X-API-Key), read-only and read-write scopes. Mint / revoke / hard-delete keys from /admin?tab=api_keys. CSRF short-circuits on /api/* because bearer auth doesn't ride on cookies.
  • Multi-role auth. Anonymous (read-only) Β· Librarian (catalog + loans) Β· Admin (everything). Session inactivity timeout with keep-alive toast. Four UI languages β€” English, French, German, Italian β€” with per-user preference toggle.
  • Hardened by construction. Strict CSP (no unsafe-inline/unsafe-eval), CSRF synchronizer-token middleware on every state-changing request with server-rendered "session expired" feedback, scanner-guard against burst-keyboard input leaking into modals.
  • Admin panel. Health dashboard (entity counts, MariaDB version, disk usage, provider reachability), user management with last-active-admin guard, editable reference data (genres, volume states, contributor roles, location node types), system settings (loans / providers / language / valuation / logging level), trash view + restore + permanent delete, configurable auto-purge after 30 days.
  • Production observability (v1.7.0+, completed in v1.7.1). Persistent daily-rotating log files with 30-day in-process purge. Admin-controlled log level (trace / debug / info / warn / error or full tracing-subscriber EnvFilter directives) flippable from /admin > System without a redeploy.
  • First-launch setup wizard. Fresh installs walk through Admin β†’ Providers β†’ Preferences β†’ Done.
  • Mobile-aware + WCAG 2.2 AA accessible. Dual-surface mobile UX (desktop tables collapse into cards, admin tabs into <select>), full keyboard navigation with shortcuts cheat-sheet (?), contextual help-icon tooltips, and an axe-core CI gate over the main surfaces (thirteen of them, listed in docs/accessibility-audit.md⁠ β€” the newer pages are not in the set yet).

⁠Quick start

⁠Minimal docker-compose.yml
services:
  mybibli:
    image: gcorbaz/mybibli:latest
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: mysql://mybibli:mybibli@db:3306/mybibli?charset=utf8mb4
      HOST: "0.0.0.0"
      PORT: "8080"
      # v1.7.0+: persistent file logging + admin-controlled level.
      # Defaults below are production-safe; admins can flip the live
      # filter from /admin > System without restarting the container.
      MYBIBLI_LOG_LEVEL: info
      MYBIBLI_LOG_DIR: /var/log/mybibli
      # v1.7.1+: per-probe timeout for the /admin > Health
      # reachability check. Bump on fragile uplinks (default 10s
      # is conservative for home-NAS networks).
      MYBIBLI_PROVIDER_HEALTH_TIMEOUT_SECS: "10"
    volumes:
      # Issue #213 β€” cover JPGs MUST persist across container upgrades.
      # Without this mount, every `docker compose up -d` after a pull
      # destroys the writable layer and the cataloged covers vanish.
      - mybibli-covers:/app/covers
      # v1.7.0+ β€” persistent daily-rotating log files (Operator can
      # `docker compose exec mybibli tail -f /var/log/mybibli/mybibli.log.$(date -u +%Y-%m-%d)`).
      # Forensic-only; safe to wipe at any time. Drop this mount if
      # you only need `docker compose logs` (no on-disk retention).
      - mybibli-logs:/var/log/mybibli
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mariadb:11
    environment:
      MARIADB_ROOT_PASSWORD: changeme
      MARIADB_DATABASE: mybibli
      MARIADB_USER: mybibli
      MARIADB_PASSWORD: mybibli
    volumes:
      - mybibli-db:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mybibli-db:
  mybibli-covers:
  mybibli-logs:

Run it:

docker compose pull
docker compose up -d

Open http://localhost:8080. The first-launch wizard greets you. Create the admin account. You're in.

⁠Environment reference

Configuration comes in two layers, and the distinction matters:

  • Deployment-time, environment variables β€” database URL, host/port, cookie and CSP hardening, log directory, the dev/test overrides. There is no config file; the canonical reference with every variable commented is .env.example⁠ in the repo.
  • Run-time, the admin panel β€” loan thresholds, session timeout, provider API keys and per-provider timeouts, interface language, valuation display, log level. These live in the database and are edited in Admin β†’ System, taking effect on the next request with no restart. Several of them (MYBIBLI_LOG_LEVEL, MYBIBLI_PROVIDER_HEALTH_TIMEOUT_SECS, the provider API keys) also exist as environment variables: that is a one-shot seeding path for a fresh deployment, applied while the stored value is still the default. Once you save the setting in the panel, the panel wins and the variable is inert.
⁠Bind-mount alternatives (Synology DSM, journald shipping, etc.)

Both mybibli-covers and mybibli-logs can be swapped from Docker-named volumes to host bind mounts. Pick a host directory (e.g. /volume1/docker/mybibli/covers, /volume1/docker/mybibli/logs) and replace the volume line with - /your/host/path:/app/covers / - /your/host/path:/var/log/mybibli. The full operator manual (chapter 1 install + chapter 12 operations) walks through it β€” see the GitHub release page⁠ for the PDF.

⁠Tags

  • :latest β€” tracks the highest semver release tag.
  • :1.20.0 (current), :1.19.0, :1.18.0 and every prior release tag back to :1.1.0 β€” specific releases. Pin to a specific tag in production-style setups; tracking :latest is reasonable for homelab. The full tag list is on the Tags tab⁠.
  • No :dev, no :main, no :beta published β€” tagged releases only.

⁠Docs

  • End-user manual (PDF, EN + FR) β€” attached to each GitHub Release⁠, and committed to the repo at docs/manual/mybibli-manual-{en,fr}.pdf so a git checkout vX.Y.Z always carries the matching manual.
  • Operator README β€” github.com/guycorbaz/mybibli⁠ β€” install + configure + run-locally + dev-stack.
  • Operations & debugging (chapter 12 of the manual) β€” log location, tailing, log levels, structured JSON parsing, post-mortem grepping.
  • Auth threat model β€” docs/auth-threat-model.md⁠ β€” what CSRF protects, what session cookies do, why the single-tenant LAN/NAS shape lets us simplify some auth surfaces.
  • Roadmap + release timeline β€” guycorbaz.github.io/mybibli/roadmap.html⁠.

⁠Contributing / issues / requests

⁠License

GNU AGPL v3 or later⁠. If you run a modified version (including hosted-as-a-service), you must offer the corresponding source to your users.

Tag summary

Content type

Image

Digest

sha256:fd09a2904…

Size

17.5 MB

Last updated

10 days ago

docker pull gcorbaz/mybibli