An open source, BYOD(Bring Your Own Dataset) character sheet creator / guide for a certain TTRPG.
839
A character sheet creator, a searchable reference and a dice tray for a certain TTRPG — over a library you supply yourself.
grimoire ships no game content and redistributes none. The image is the application: no spells, no monsters, no rules text. You point it at your own dataset, which is copied into your browser and never leaves your machine.
docker run --rm -p 5173:8080 s1r1usblack/grimoire:nightly
Then open http://localhost:5173 and attach a library from the first screen.
Or with compose:
services:
grimoire:
image: s1r1usblack/grimoire:nightly
ports:
- "5173:8080"
restart: unless-stopped
Nothing else is needed — no dataset on the host, no volume to prepare, no configuration, no database.
Node and the built static files, and that is all. No node_modules, no web
server, nothing installed: a small script hands out dist and does only that —
fingerprinted assets held for a year, everything else revalidated against an
ETag, gzip on the way out. Put nginx or Caddy in front if you want one; this
image does not presume to bring its own.
| Listens on | 8080 (PORT and HOST are overridable) |
| Runs as | node, not root |
| Healthcheck | built in, hits / |
| Platform | linux/amd64 |
| Base | node:24-alpine |
There is no backend and no database. Every library, character and setting lives in the browser that created them, so the container stores nothing and throwing it away costs nothing.
That is also the shape of its exposure: someone else on your network who opens your instance gets their own empty first-run screen, not your characters. What is published is the app and a static file server. There are no accounts, so put authentication in front if the network is not one you trust — it protects the service rather than your sheets.
The address is part of your data's address. Browsers key storage by origin —
scheme, host and port together — so http://localhost:5173 and
http://192.168.1.10:5173 are two separate stores with nothing shared between
them. Move the app and it opens on the first-run screen as though your
libraries were gone. They are not gone; they are at the address they were
attached at. Decide the URL you mean to keep before you build a character on
it, and move anything already stored with Export and Import in Settings.
Plain http makes the folder picker one-shot. Browsers grant the File
System Access API only in a secure context — https://, or localhost. Over
http://192.168.x.x attaching a library still works, and the dataset is copied
into the browser either way; what you lose is the reopenable handle, so
refreshing that library from disk means choosing the folder again. A zipped
dataset needs none of that API and behaves the same at any address. Put TLS in
front and the handle comes back — the proxy may talk plain http to this
container, since the browser never sees that hop. Serve it at a host root
rather than a sub-path; the built page references its assets absolutely.
| Tag | What it is |
|---|---|
nightly | The current build. Moves. |
grimoire is free software under the GNU Affero General Public License, version 3 or later. It comes with absolutely no warranty, and you are welcome to redistribute and modify it under those terms.
Source: https://gitea.com/AndrewFeelz/grimoire
A running instance serves its own licence at /LICENSE.txt and the notices for
its bundled third-party components — React and ajv under MIT, fast-uri under
BSD-3-Clause — at /THIRD-PARTY-NOTICES.txt. Both links are in the app, under
About grimoire in Settings.
Whatever dataset you attach stays under its own terms. That is between you and whoever wrote it, and is not something this image can determine — which is why it contains none of it.
Content type
Image
Digest
sha256:6ab5a6801…
Size
60.3 MB
Last updated
17 days ago
docker pull s1r1usblack/grimoire:nightly