Skip to content

All-Might — Setup

Media library server hosting Grimmory (books/manga), RomM (game ROMs), and Shoko Server (anime collection management). Runs on a dedicated Debian LXC (116) with a 4TB Crucial MX500 SSD mounted at /unohana. Each service is deployed independently with its own Docker Compose stack and Forgejo workflow.

  • Grimmory: https://github.com/grimmory-tools/grimmory
  • RomM: https://github.com/rommapp/romm
  • Shoko Server: https://github.com/ShokoAnime/ShokoServer

Infrastructure

Host LXC ID IP Resources Storage
Debian LXC 116 192.168.1.116 4 cores, 4 GB RAM, 16 GB root disk 4TB SSD (ata-CT4000MX500SSD1_2336E873A527-part1) at /unohana

Services

Service Container Port URL Database
Grimmory grimmory 6060 https://library.eva-00.network MariaDB (grimmory db)
RomM romm 8080 https://romm.eva-00.network MariaDB (romm db)
Shoko Server shoko-server 8111 https://shoko.eva-00.network SQLite (internal)
MariaDB 11.4.5 mariadb 3306 Internal only

Jellyfin integration

The 4TB disk is bind-mounted read-only into Jellyfin (LXC 114) at /unohana. Jellyfin can serve anime from /unohana/shoko/anime without any network filesystem overhead.

Configured via: - jellyfin-host-gpu.yml: adds mp1: /mnt/all-might,mp=/unohana,ro=1 to LXC 114 conf - services/jellyfin/docker-compose.yml: mounts /unohana:/unohana:ro

Observability

Logs

Logs are collected via Grafana Alloy Docker discovery and shipped to Loki.

Query Purpose
{container="grimmory"} Grimmory application logs
{container="grimmory"} \|= "error" Grimmory errors only
{container="romm"} RomM application logs
{container="shoko-server"} Shoko Server logs
{container="mariadb", host="all-might"} MariaDB logs

Access: Grafana → Explore → Loki → Enter query

Health checks

# Grimmory
curl http://192.168.1.116:6060/api/v1/healthcheck

# RomM
curl http://192.168.1.116:8080

# Shoko Server
curl http://192.168.1.116:8111

IaC

Shared infrastructure (LXC, Docker, Alloy)

Artifact Path
Playbook ansible/playbooks/all-might.yml
Workflow .forgejo/workflows/all-might.yml

MariaDB

Artifact Path
Playbook ansible/playbooks/all-might-mariadb.yml
Workflow .forgejo/workflows/all-might-mariadb.yml
Compose services/mariadb/docker-compose.yml

Grimmory

Artifact Path
Playbook ansible/playbooks/all-might-grimmory.yml
Workflow .forgejo/workflows/all-might-grimmory.yml
Compose services/grimmory/docker-compose.yml

RomM

Artifact Path
Playbook ansible/playbooks/all-might-romm.yml
Workflow .forgejo/workflows/all-might-romm.yml
Compose services/romm/docker-compose.yml

Shoko Server

Artifact Path
Playbook ansible/playbooks/all-might-shoko.yml
Workflow .forgejo/workflows/all-might-shoko.yml
Compose services/shoko/docker-compose.yml

Secrets

MariaDB (secret/all-might-mariadb)

Key Purpose
mysql_root_password MariaDB root password
grimmory_db_password Grimmory database user password
romm_db_password RomM database user password

Note: The MariaDB playbook also creates the grimmory and romm databases and users automatically.

Grimmory (secret/all-might-grimmory)

Key Purpose
db_user Database username (default: grimmory)
db_password Database password
db_name Database name (default: grimmory)
pocketid_client_id PocketID OIDC client ID
pocketid_client_secret PocketID OIDC client secret
grimmory_username Admin username for first-run setup
grimmory_password Admin password for first-run setup
grimmory_email Admin email for first-run setup
grimmory_name Admin display name for first-run setup

RomM (secret/all-might-romm)

Key Purpose
db_user Database username (default: romm)
db_password Database password
db_name Database name (default: romm)
romm_auth_secret_key Auth secret (generate via openssl rand -hex 32)
igdb_client_id IGDB API client ID (optional, for game metadata)
igdb_client_secret IGDB API client secret (optional)
retroachievements_api_key RetroAchievements API key (optional)
pocketid_client_id PocketID OIDC client ID
pocketid_client_secret PocketID OIDC client secret
romm_username Admin username for first-run setup
romm_password Admin password for first-run setup
romm_email Admin email for first-run setup

Shoko Server (secret/all-might-shoko)

Key Purpose
anidb_username AniDB account username
anidb_password AniDB account password
shoko_username Admin username for first-run setup
shoko_password Admin password for first-run setup
shoko_api_key API key (auto-generated and stored back by playbook)

Folder structure (/unohana)

/unohana/
├── grimmory/
│   ├── books/        # Book library (ebooks, manga, comics, audiobooks)
│   ├── bookdrop/     # Watched folder — auto-detects and imports new files
│   └── data/         # Application data (thumbnails, cache, etc.)
├── romm/
│   ├── roms/         # ROM library, organized by platform: roms/{platform}/
│   ├── bios/         # BIOS files per platform (optional): bios/{platform}/
│   ├── assets/       # Saves, states, uploads
│   └── config/       # RomM configuration
├── shoko/
│   ├── anime/        # Anime collection files
│   ├── drop/         # Watched folder — drop new files here for import
│   └── shoko-config/ # Persistent Shoko config (SQLite DB, settings)
└── config/           # Shared config backups

Grimmory supported formats

  • eBooks: EPUB, MOBI, AZW, AZW3, FB2
  • Documents: PDF
  • Comics: CBZ, CBR, CB7
  • Audiobooks: M4B, M4A, MP3, OPUS

RomM library organization

RomM uses Structure A (recommended): platform subdirectories under roms/:

roms/
├── gba/
├── snes/
├── ps2/
└── switch/

Deploy order

  1. LXC provisioningall-might.yml (creates LXC, mounts disk, installs Docker)
  2. MariaDBall-might-mariadb.yml (must be running before Grimmory or RomM)
  3. Grimmoryall-might-grimmory.yml (any order after MariaDB)
  4. RomMall-might-romm.yml (any order after MariaDB)
  5. Shoko Serverall-might-shoko.yml (independent, no DB dependency)
  6. Jellyfin update — trigger jellyfin-host-gpu.yml + jellyfin.yml (requires LXC 114 restart)
  7. Caddy — auto-triggers from Caddyfile changes

First-run setup (automated)

All three services have fully automated first-run setup via their Ansible playbooks — no GUI wizard required:

  • Grimmory: Admin user created via POST /api/v1/setup, libraries created via POST /api/v1/libraries, OIDC configured via PUT /api/v1/settings (Grimmory stores OIDC config in its database, not env vars)
  • RomM: Admin user created via POST /api/users (unauthenticated when no admins exist), metadata scan priorities preseeded via config.yml, OIDC configured via env vars
  • Shoko Server: Admin user and import folders configured via API after first boot

Use force_clean=true in the Forgejo workflow dispatch to wipe and redo first-run setup (resets database for Grimmory/RomM).

Post-deploy manual steps

  • Jellyfin: Add new libraries pointing to /unohana/shoko/anime (and optionally /unohana/grimmory/books)

Glance dashboard

All three services have bookmarks and health-check monitors in the Glance dashboard (services/glance/glance.yml).

Icon sources

Service Icon Source
Grimmory di:book-lore Dashboard Icons (via former name BookLore)
RomM di:romm Dashboard Icons
Shoko di:shokoanime Dashboard Icons

Icons use the di: prefix for dashboard-icons (sourced from https://selfh.st/icons/). The si: prefix is for Simple Icons. Prefer di: for self-hosted apps as it has better coverage.