Phase 1 — fix stale state after strong migration (Phase 1+2, 2026-07-05)
- README: corrected IPs (jellyfin 206→246, arriman 132→245, etc.),
added missing containers (128 trmnl, 129 house, 133 seanime, 134 romm,
124 authentik), updated last-refreshed date, added strong host context
- containers/101-jellyfin.md: IP 206→246, host hubris→strong, mount
/mnt/library→/mnt/media_local, GPU 760M→680M+RX7600, privilege→priv
- containers/118-elementsynapse.md: IP 239→242, added Host: strong
- containers/122-arriman.md: IP 132→245, mount→/mnt/media_local, added Host
- containers/129-house.md: IP 212→244, added Host: strong
- containers/130-grimmory.md: IP 213→247, mount→/mnt/media_local, added Host
- containers/121-caddy.md: fixed site list (books→grimmory, removed auth→VPS,
added house, roms, teddy, trmnl)
- hosts/strong.md: updated At-a-glance to reflect 7 LXCs hosted
- containers/123-claudio-bot.md, 127-mule-photos-new.md: archived to
containers/archive/ (were destroyed LXCs with living pages)
- inventory.yaml: verified correct — no changes needed
Phase 2 — structural cleanup
- infrastructure/index.md: one-page overview of all cross-cutting systems
- runbooks/: moved runbook-budget-from-csv.md and runbook-dpkg-interrupted.md
from operations/ with YAML frontmatter added
- plans/done/: moved 4 completed plans out of active view; updated index
- vms/index.md: added VM index page
Phase 3 — navigation & discoverability
- GLOSSARY.md: term definitions (Authentik, Caddy, LXC, VAAPI, etc.)
- README: added table of contents, links to glossary + infrastructure index
- investigations/: archived 2 resolved cases (crash-loop, authentik-migration)
to investigations/archive/; updated index with active vs archived sections
Phase 4 — ongoing discipline
- CONTRIBUTING.md: documented same-session update rule with explicit checklist
- README: replaced full LXC table with summary + link to containers/index.md
(single source of truth; de-duplication)
67 lines
3.6 KiB
Markdown
67 lines
3.6 KiB
Markdown
# 130 — `grimmory`
|
|
|
|
Self-hosted digital library (eBooks, comics, audiobooks). Community fork/successor of Booklore, with smart shelves, metadata enrichment, Kobo/KOReader sync, OPDS, and a built-in EPUB/PDF reader. Migrated from [apps (105)](105-apps.md) on 2026-06-29.
|
|
|
|
## At a glance
|
|
|
|
- **Hostname:** `grimmory`
|
|
- **IP:** `192.168.8.247`
|
|
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
|
- **Privilege:** privileged (UID = host UID for `/mnt/library` media GID)
|
|
- **Resources:** 1 core / 2 GiB RAM / 16 GiB rootfs (Debian 13)
|
|
- **Mounts:** `/mnt/media_local` ↔ `/mnt/library`
|
|
- **Public hostname:** `books.hubris.network`
|
|
|
|
## Service / port map
|
|
|
|
| Service | Listen | Notes |
|
|
|---------|--------|-------|
|
|
| Grimmory | `192.168.8.247:6060` | Docker Compose at `/opt/grimmory/` |
|
|
| MariaDB | internal only | Sidecar in the same compose stack |
|
|
|
|
## Compose
|
|
|
|
Located at `/opt/grimmory/docker-compose.yml`. Key points:
|
|
|
|
- Image: `ghcr.io/grimmory-tools/grimmory:latest`
|
|
- Books library: `/mnt/library/books` → `/books` (read-write; media GID 10000 via `GROUP_ID=10000`)
|
|
- Bookdrop (watched folder for auto-import): `/opt/grimmory/bookdrop` → `/bookdrop`
|
|
- App data (covers, DB config): `/opt/grimmory/data` → `/app/data`
|
|
- MariaDB config: `/opt/grimmory/mariadb/config` → `/config` (linuxserver/mariadb image)
|
|
- `extra_hosts: auth.hubris.network:192.168.8.175` — routes Authentik OIDC discovery to Caddy from inside the container
|
|
- `FORCE_DISABLE_OIDC=false` — OIDC stays enabled; provider configured via Grimmory admin UI
|
|
|
|
Credentials live in `/opt/grimmory/.env` (untracked):
|
|
- `DATABASE_PASSWORD` / `MYSQL_PASSWORD` — MariaDB Grimmory user password
|
|
- `MYSQL_ROOT_PASSWORD` — MariaDB root password
|
|
|
|
## Authentik OIDC
|
|
|
|
Uses Confidential client (client secret stored in Grimmory's DB — migrated from Booklore). The OIDC config carried over in the database dump; no manual re-entry needed.
|
|
|
|
- **Authentik provider:** `Provider for Grimmory` (renamed from `Provider for Booklore` on migration)
|
|
- **Client ID:** `L1u0eFsNhbKgiIvvFeIr2mvZdbtFyzidCq2h6thL`
|
|
- **Client type:** Confidential (client secret in `oidc_provider_details` in MariaDB `app_settings`)
|
|
- **Redirect URI:** `https://books.hubris.network/oauth2-callback`
|
|
- **Scopes:** openid, profile, email, offline_access
|
|
- **Back-channel logout:** `http://192.168.8.247:6060/api/v1/auth/oidc/backchannel-logout`
|
|
- **Application slug:** `booklore` → Issuer URI: `https://auth.hubris.network/application/o/booklore/`
|
|
|
|
## Media permissions
|
|
|
|
LXC is privileged → in-container UID = host UID. Docker container gets media GID via `GROUP_ID=10000` env var (Grimmory/linuxserver pattern). The `/mnt/library/books` subtree is owned `:media` mode `2775` (setgid). See [media-permissions](../infrastructure/media-permissions.md).
|
|
|
|
## Related
|
|
|
|
- [apps (105)](105-apps.md) — previous host (Booklore)
|
|
- [Caddy (121)](121-caddy.md) — `books.hubris.network → 192.168.8.247:6060`
|
|
- [Authentik (124)](124-authentik.md) — OIDC provider `Grimmory`
|
|
- [DNS (107)](107-dns.md) — `books.hubris.network → 192.168.8.175` (unchanged from Booklore)
|
|
- [Media permissions](../infrastructure/media-permissions.md)
|
|
|
|
## Changelog
|
|
|
|
### 2026-06-29 — provisioned; Booklore migrated
|
|
|
|
LXC 130 created (Debian 13, privileged, `192.168.8.213`). Docker installed. Grimmory compose deployed at `/opt/grimmory/`. MariaDB dump from Booklore (LXC 105) restored — schema-compatible since Grimmory is a direct fork. Caddy `books.hubris.network` backend updated from `192.168.8.205:6060` to `192.168.8.213:6060`. Authentik provider updated: Booklore → Grimmory, Confidential → Public (PKCE). Booklore stack removed from Portainer on LXC 105.
|