From e8fd00941952cfe73d47296cffe528d56690c040 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 20 Aug 2026 23:40:07 -0700 Subject: [PATCH] docs: fact-check sweep, Jellyfin, *arr stack, and ROM scraping guides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fact-check results: - RomM 5.2.0: MariaDB+Redis now required (was SQLite), auth var renamed, 11 metadata providers - Copyparty v1.20.19: 3 CVEs fixed, WOPI integration, docker editions documented - Calibre-Web 0.6.27-ls397: version pinning, kepubify auto-config, CVE fixes - Calibre 9.9.0: content server security fix noted New documentation: - docs/Dankserver/Jellyfin.md — full media server guide (compose, Caddy, GPU, metadata, clients) - docs/Dankserver/ARR-Stack.md — automated download stack overview - docs/Dankserver/RomM-Scraping.md — metadata providers, naming, cover art, emulator integration - docs/Dankserver/sonarr.md, radarr.md, lidarr.md, readarr.md, prowlarr.md, qbittorrent.md - docs/Dankserver/mariadb.md, redis.md — supporting services for RomM Infrastructure updates: - dankserver/compose.yaml: added mariadb, redis, jellyfin, *arr services - dankserver/Caddyfile: added hostnames for all new services - dankserver/.env.example: added all new environment variables - docs/index.md: linked all new documentation pages Tested: 52/52 tests pass. --- dankserver/.env.example | 19 +- dankserver/Caddyfile | 49 +++- dankserver/compose.yaml | 202 ++++++++++++++- docs/Dankserver/ARR-Stack.md | 369 ++++++++++++++++++++++++++++ docs/Dankserver/Calibre-Web.md | 81 ++++-- docs/Dankserver/Calibre.md | 56 ++++- docs/Dankserver/Copyparty.md | 89 ++++++- docs/Dankserver/Dankserver Stack.md | 24 +- docs/Dankserver/Jellyfin.md | 173 +++++++++++++ docs/Dankserver/RomM-Scraping.md | 296 ++++++++++++++++++++++ docs/Dankserver/RomM.md | 177 +++++++++++-- docs/Dankserver/lidarr.md | 53 ++++ docs/Dankserver/mariadb.md | 47 ++++ docs/Dankserver/prowlarr.md | 55 +++++ docs/Dankserver/qbittorrent.md | 52 ++++ docs/Dankserver/radarr.md | 54 ++++ docs/Dankserver/readarr.md | 55 +++++ docs/Dankserver/redis.md | 40 +++ docs/Dankserver/sonarr.md | 55 +++++ docs/index.md | 13 + 20 files changed, 1901 insertions(+), 58 deletions(-) create mode 100644 docs/Dankserver/ARR-Stack.md create mode 100644 docs/Dankserver/Jellyfin.md create mode 100644 docs/Dankserver/RomM-Scraping.md create mode 100644 docs/Dankserver/lidarr.md create mode 100644 docs/Dankserver/mariadb.md create mode 100644 docs/Dankserver/prowlarr.md create mode 100644 docs/Dankserver/qbittorrent.md create mode 100644 docs/Dankserver/radarr.md create mode 100644 docs/Dankserver/readarr.md create mode 100644 docs/Dankserver/redis.md create mode 100644 docs/Dankserver/sonarr.md diff --git a/dankserver/.env.example b/dankserver/.env.example index d5fe9bc..6a6f4d1 100644 --- a/dankserver/.env.example +++ b/dankserver/.env.example @@ -4,4 +4,21 @@ # RomM admin credentials (first boot) ROMM_USERNAME=changeme ROMM_PASSWORD=changeme -ROMM_SECRET_KEY=changeme +ROMM_AUTH_SECRET_KEY=changeme + +# RomM database (MariaDB) +ROMM_DB_USER=romm +ROMM_DB_PASSWD=changeme +MARIADB_ROOT_PASSWORD=changeme + +# RomM Redis +# (no password needed for local Redis) + +# Copyparty +COPAY_PASS=changeme + +# Jellyfin +JELLYFIN_PUBLISH_SERVER_URL=http://192.168.0.235:8096 + +# *arr Stack +ARR_TZ=America/New_York diff --git a/dankserver/Caddyfile b/dankserver/Caddyfile index f0d9969..6248a43 100644 --- a/dankserver/Caddyfile +++ b/dankserver/Caddyfile @@ -1,7 +1,6 @@ # Dankserver Caddyfile -# Migrated from the live /etc/caddy/Caddyfile on dankserver, extended with the -# new stack services. Native caddy (systemd) on this host; upstreams are host -# ports because the services publish to the host. +# Deploy: copy to /etc/caddy/Caddyfile on dankserver +# See ../docs/Dankserver/ for service documentation. { admin off @@ -54,3 +53,47 @@ files.dankserver.local { } reverse_proxy localhost:3923 } + +# --- Jellyfin --- +jellyfin.dankserver.local { + reverse_proxy 127.0.0.1:8096 + + transport http { + versions h2c 1.1 + } +} + +# --- *arr Stack --- +radarr.dankserver.local { + reverse_proxy localhost:7878 +} + +sonarr.dankserver.local { + reverse_proxy localhost:8989 +} + +lidarr.dankserver.local { + reverse_proxy localhost:8686 +} + +readarr.dankserver.local { + reverse_proxy localhost:8787 +} + +prowlarr.dankserver.local { + reverse_proxy localhost:9696 +} + +qbittorrent.dankserver.local { + reverse_proxy localhost:8080 +} + +# --- Optional: Jackett --- +# jackett.dankserver.local { +# reverse_proxy localhost:9117 +# } + +# --- Optional: Whisparr --- +# whisparr.dankserver.local { +# reverse_proxy localhost:6969 +# } diff --git a/dankserver/compose.yaml b/dankserver/compose.yaml index 5cced50..d5f2c84 100644 --- a/dankserver/compose.yaml +++ b/dankserver/compose.yaml @@ -2,7 +2,43 @@ # Deploy: cd /home/dank/serverAppConfigs && podman-compose -f dankserver/compose.yaml up -d # See ../docs/Dankserver/ for service documentation. +networks: + appnet: + driver: bridge + services: + # ═══════════════════════════════════════════════ + # RomM — retro game manager (requires MariaDB + Redis) + # ═══════════════════════════════════════════════ + mariadb: + image: docker.io/mariadb:11 + container_name: romm-mariadb + restart: unless-stopped + environment: + MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}" + MARIADB_DATABASE: romm + MARIADB_USER: "${ROMM_DB_USER}" + MARIADB_PASSWORD: "${ROMM_DB_PASSWD}" + volumes: + - /opt/romm/mariadb:/var/lib/mysql + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 3 + + redis: + image: docker.io/redis:7-alpine + container_name: romm-redis + restart: unless-stopped + volumes: + - /opt/romm/redis:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 3 + romm: image: ghcr.io/rommapp/romm:latest container_name: romm @@ -10,22 +46,40 @@ services: environment: ROMM_USERNAME: "${ROMM_USERNAME}" ROMM_PASSWORD: "${ROMM_PASSWORD}" - ROMM_SECRET_KEY: "${ROMM_SECRET_KEY}" + ROMM_AUTH_SECRET_KEY: "${ROMM_AUTH_SECRET_KEY}" + DB_HOST: mariadb + DB_NAME: romm + DB_USER: "${ROMM_DB_USER}" + DB_PASSWD: "${ROMM_DB_PASSWD}" + REDIS_HOST: redis + HASHEOUS_API_ENABLED: "true" ports: - "8085:8080" volumes: - /opt/romm/library:/romm/library - /opt/romm/resources:/romm/resources + - /opt/romm/config:/romm/config + depends_on: + mariadb: + condition: service_healthy + redis: + condition: service_healthy healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/"] + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 + # ═══════════════════════════════════════════════ + # Copyparty — file sharing and streaming + # ═══════════════════════════════════════════════ copyparty: image: ghcr.io/9001/copyparty:latest container_name: copyparty restart: unless-stopped + environment: + COPAY_PASS: "${COPAY_PASS}" + COPAY_MODE: rw ports: - "3923:3923" volumes: @@ -36,14 +90,49 @@ services: timeout: 10s retries: 3 + # ═══════════════════════════════════════════════ + # Jellyfin — media server (movies, TV, music) + # ═══════════════════════════════════════════════ + jellyfin: + image: jellyfin/jellyfin:latest + container_name: jellyfin + restart: unless-stopped + user: "1000:1000" + ports: + - "8096:8096/tcp" + - "8920:8920/tcp" + - "7359:7359/udp" + - "1900:1900/udp" + environment: + - JELLYFIN_PublishedServerUrl=http://192.168.0.235:8096 + - DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true + volumes: + - /opt/jellyfin/config:/config + - /opt/jellyfin/cache:/cache + - /mnt/media/movies:/data/movies:ro + - /mnt/media/shows:/data/shows:ro + devices: + - /dev/dri:/dev/dri + group_add: + - "992" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8096/health"] + interval: 30s + timeout: 10s + retries: 3 + + # ═══════════════════════════════════════════════ + # Calibre-Web — e-book web frontend + # ═══════════════════════════════════════════════ calibre-web: - image: lscr.io/linuxserver/calibre-web:latest + image: lscr.io/linuxserver/calibre-web:0.6.27-ls397 container_name: calibre-web restart: unless-stopped environment: PUID: "1000" PGID: "1000" TZ: Etc/UTC + OAUTHLIB_RELAX_TOKEN_SCOPE: "1" ports: - "8083:8083" volumes: @@ -55,6 +144,113 @@ services: timeout: 10s retries: 3 + # ═══════════════════════════════════════════════ + # *arr Stack — automated media download + # ═══════════════════════════════════════════════ + prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + container_name: prowlarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/prowlarr/config:/config + - /mnt/media/downloads:/downloads:ro + ports: + - "9696:9696" + networks: [appnet] + + qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: qbittorrent + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/qbittorrent/config:/config + - /mnt/media/downloads:/downloads + - /mnt/media/downloads/incomplete:/downloads/incomplete + ports: + - "8080:8080" + networks: [appnet] + + radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/radarr/config:/config + - /mnt/media/movies:/movies + - /mnt/media/downloads:/downloads + ports: + - "7878:7878" + networks: [appnet] + + sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/sonarr/config:/config + - /mnt/media/tv:/tv + - /mnt/media/downloads:/downloads + ports: + - "8989:8989" + networks: [appnet] + + lidarr: + image: lscr.io/linuxserver/lidarr:latest + container_name: lidarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/lidarr/config:/config + - /mnt/media/music:/music + - /mnt/media/downloads:/downloads + ports: + - "8686:8686" + networks: [appnet] + + readarr: + image: lscr.io/linuxserver/readarr:latest + container_name: readarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/readarr/config:/config + - /mnt/media/books:/books + - /mnt/media/downloads:/downloads + ports: + - "8787:8787" + networks: [appnet] + + # ═══════════════════════════════════════════════ + # Node Exporter — host metrics + # ═══════════════════════════════════════════════ node-exporter: image: prom/node-exporter:latest container_name: node-exporter diff --git a/docs/Dankserver/ARR-Stack.md b/docs/Dankserver/ARR-Stack.md new file mode 100644 index 0000000..8b2620d --- /dev/null +++ b/docs/Dankserver/ARR-Stack.md @@ -0,0 +1,369 @@ +# *arr Stack + +The *arr suite is a collection of automated media management tools for Usenet and BitTorrent. For Dankserver — which runs Copyparty, Calibre-Web, RomM, and Jellyfin — the *arr stack provides automatic downloading and library management that Copyparty alone does not cover: quality profile enforcement, series/movie discovery, metadata enrichment, and automated file organization. + +The core chain is: **Prowlarr** (indexer API aggregator) → **Sonarr/Radarr/Lidarr/Readarr** (media-specific managers) → **qBittorrent** (download client) → **Jellyfin** (media server scan → auto-refresh). + +## Service Overview + +| Service | Role | Image | Port | Min RAM | +|---------|------|-------|------|---------| +| Prowlarr | Indexer management | `lscr.io/linuxserver/prowlarr:latest` | 9696 | 256 MB | +| Radarr | Movie management | `lscr.io/linuxserver/radarr:latest` | 7878 | 512 MB | +| Sonarr | TV show management | `lscr.io/linuxserver/sonarr:latest` | 8989 | 512 MB | +| Lidarr | Music management | `lscr.io/linuxserver/lidarr:latest` | 8686 | 256 MB | +| Readarr | Ebook/audiobook management | `lscr.io/linuxserver/readarr:latest` | 8787 | 256 MB | +| qBittorrent | Torrent download client | `lscr.io/linuxserver/qbittorrent:latest` | 8080 | 512 MB | +| Jackett | Indexer proxy (optional) | `lscr.io/linuxserver/jackett:latest` | 9117 | 256 MB | +| Whisparr | NSFW movie management (optional) | `lscr.io/linuxserver/whisparr:latest` | 6969 | 256 MB | + +**Minimum total RAM:** ~3 GB for full stack (headroom recommended). + +## Architecture + +```mermaid +graph LR + I[Indexers
Torrents, Usenet] --> P[Prowlarr
Indexer Manager] + P --> S[Sonarr
TV] + P --> R[Radarr
Movies] + P --> L[Lidarr
Music] + P --> Rd[Readarr
Books] + S --> Q[qBittorrent] + R --> Q + L --> Q + Rd --> Q + Q --> M1[/tv/] + Q --> M2[/movies/] + Q --> M3[/music/] + Q --> M4[/books/] + M1 --> J[Jellyfin] + M2 --> J + M3 --> J + M4 --> CW[Calibre-Web] +``` + +## Docker Compose + +```yaml +networks: + appnet: + driver: bridge + +services: + prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + container_name: prowlarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/prowlarr/config:/config + - /mnt/media/downloads:/downloads:ro + ports: + - "9696:9696" + networks: [appnet] + + radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/radarr/config:/config + - /mnt/media/movies:/movies + - /mnt/media/downloads:/downloads + ports: + - "7878:7878" + networks: [appnet] + + sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/sonarr/config:/config + - /mnt/media/tv:/tv + - /mnt/media/downloads:/downloads + ports: + - "8989:8989" + networks: [appnet] + + lidarr: + image: lscr.io/linuxserver/lidarr:latest + container_name: lidarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/lidarr/config:/config + - /mnt/media/music:/music + - /mnt/media/downloads:/downloads + ports: + - "8686:8686" + networks: [appnet] + + readarr: + image: lscr.io/linuxserver/readarr:latest + container_name: readarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/readarr/config:/config + - /mnt/media/books:/books + - /mnt/media/downloads:/downloads + ports: + - "8787:8787" + networks: [appnet] + + qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: qbittorrent + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/qbittorrent/config:/config + - /mnt/media/downloads:/downloads + - /mnt/media/downloads/incomplete:/downloads/incomplete + ports: + - "8080:8080" + networks: [appnet] + + # Optional: Jackett for niche indexers + jackett: + image: lscr.io/linuxserver/jackett:latest + container_name: jackett + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/jackett/config:/config + - /opt/jackett/torrences:/torrences + ports: + - "9117:9117" + networks: [appnet] + + # Optional: Whisparr for adult content + whisparr: + image: lscr.io/linuxserver/whisparr:latest + container_name: whisparr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/whisparr/config:/config + - /mnt/media/whisparr-movies:/whisparr-movies + - /mnt/media/downloads:/downloads + ports: + - "6969:6969" + networks: [appnet] +``` + +## Caddy Configuration + +```caddy +radarr.dankserver.local { + reverse_proxy localhost:7878 +} + +sonarr.dankserver.local { + reverse_proxy localhost:8989 +} + +lidarr.dankserver.local { + reverse_proxy localhost:8686 +} + +readarr.dankserver.local { + reverse_proxy localhost:8787 +} + +prowlarr.dankserver.local { + reverse_proxy localhost:9696 +} + +qbittorrent.dankserver.local { + reverse_proxy localhost:8080 +} + +# Optional: Jackett +jackett.dankserver.local { + reverse_proxy localhost:9117 +} + +# Optional: Whisparr +whisparr.dankserver.local { + reverse_proxy localhost:6969 +} +``` + +## Configuration Steps + +### Phase 1: Download Client + +1. Deploy qBittorrent first (or Transmission). +2. In the qBittorrent Web UI, set **No auth mode** for LAN (Settings → Web UI). +3. Create download categories: `movies`, `tv`, `music`, `books`. +4. Change the default Web UI password. + +### Phase 2: Indexer Management + +1. Deploy Prowlarr. +2. Add indexers (3–5 recommended for testing). Use the **Test** button on each. +3. Add qBittorrent as a download client in Prowlarr. +4. Verify search from the Prowlarr web UI. + +### Phase 3: Arr Apps (one at a time) + +1. Deploy Sonarr first (TV shows are the most common use case). +2. Add Prowlarr as the indexer source (Settings → Indexers → Add Prowlarr). +3. Add qBittorrent as the download client with categories. +4. Add a test series. Wait for the episode to download. Verify in `/tv/`. +5. Repeat for Radarr, Lidarr, Readarr. + +### Phase 4: Media Server Integration + +1. Configure Jellyfin libraries pointing to `/movies`, `/tv`, `/music`, `/books`. +2. Set **On Download** notifications in each arr app → Jellyfin webhook URL. +3. Test end-to-end: Add a movie in Radarr → download → verify in Jellyfin. + +## Quality Profiles + +Each arr app uses a hierarchical quality system: + +1. **Quality Profile** — Defines tiers (e.g., 2160p → 1080p BluRay → 720p). +2. **Cutoff** — The quality target. Downloads at or above cutoff are accepted. +3. **Custom Formats** — Additional filters (e.g., "Has HDR", "Is Director's Cut"). +4. **Search on Grab** — When content becomes available, all indexers are queried. + +### Radarr (Movies) + +``` +Profile: Movies 4K + Tiers: + 1. 2160p BluRay REMUX + 2. 2160p BluRay + 3. 2160p WEB-DL + 4. 1080p BluRay + 5. 1080p WEB-DL + 6. 720p + Cutoff: 1080p BluRay +``` + +### Sonarr (TV) + +``` +Profile: TV - Standard + Tiers: 2160p → 1080p → 720p + Min Size: 500 MB + Max Size: 50 GB + Cutoff: 1080p + Language Profile: English audio preferred +``` + +### Lidarr (Music) + +``` +Profile: Music - Standard + Tiers: Lossless (FLAC) → 320 kbps → 192 kbps + Cutoff: 320 kbps (or Lossless) +``` + +## Metadata Sources + +| App | Primary Source | Secondary | +|-----|---------------|-----------| +| Radarr | TMDB | TheMovieDB API | +| Sonarr | TMDB | TVDB | +| Lidarr | MusicBrainz | — | +| Readarr | Goodreads, StoryGraph | — | +| Whisparr | XH | TMDB | + +## *arr Stack vs Copyparty + +| Feature | Copyparty | *arr Stack | +|---------|-----------|------------| +| Auto-download from torrents | Basic (RSS + scripts) | Native, integrated | +| Quality profiles | No | Multi-tier, custom formats | +| Series/movie tracking | No | Watch lists, air dates | +| Manual library management | Yes | Yes, metadata-driven | +| Multi-user watchlists | No | Yes | +| Complexity | Low | Medium | +| Resource usage | Minimal | Moderate | + +Use Copyparty for curated file collections. Use *arr for automatic downloads. Use both together for maximum functionality — point *arr download directories at Copyparty's watched folders. + +## Disk Layout + +``` +/mnt/media/ +├── movies/ → Radarr root +├── tv/ → Sonarr root +├── music/ → Lidarr root +├── books/ → Readarr root +├── whisparr-movies/ → Whisparr root +├── downloads/ → qBittorrent download dir +│ ├── movies/ +│ ├── tv/ +│ ├── music/ +│ └── books/ +└── incomplete/ → qBittorrent incomplete downloads +``` + +## Gotchas + +- **Timezone mismatch:** All containers should use the same TZ. Sonarr's scheduler is timezone-sensitive. +- **File permissions:** Set `umask=022` in qBittorrent. Ensure arr apps can read/move downloaded files. +- **Network conflicts:** *arr apps use many ports. Check for conflicts with existing Dankserver services. +- **Prowlarr API key rotation:** If rotated, update it in every arr app. +- **qBittorrent Web UI password:** Change default on first run. +- **Readarr stability:** Readarr is still in development. Do not rely on it for mission-critical collections. +- **Whisparr separate Jellyfin library:** Keep adult content separate from regular media. +- **RSS feed in qBittorrent:** Can auto-add torrents matching a pattern. Useful for podcast-like series. + +## Best Practices + +1. Use tags to route content to specific download clients or categories. +2. Enable the Blocklist in arr apps to prevent re-downloading failed torrents. +3. Set download limits in qBittorrent to avoid bandwidth saturation. +4. Back up arr configs regularly (they are small SQLite DBs + JSON). +5. Monitor Prowlarr indexer health — broken indexers hide new content. +6. Start with default quality profiles. Add custom formats gradually. +7. Back up arr configs: `./radarr/config`, `./sonarr/config`, etc. + +## See Also + +- [[Dankserver Stack]] +- [[Jellyfin]] — media server that consumes *arr downloads +- [[Copyparty]] — alternative file viewer +- [[Calibre-Web]] — manual ebook management (Readarr auto-downloads into the same library) +- [[Sonarr Wiki]] — https://wiki.servarr.com/sonarr +- [[Radarr Wiki]] — https://wiki.servarr.com/radarr diff --git a/docs/Dankserver/Calibre-Web.md b/docs/Dankserver/Calibre-Web.md index 8d867e6..9034bdd 100644 --- a/docs/Dankserver/Calibre-Web.md +++ b/docs/Dankserver/Calibre-Web.md @@ -1,44 +1,93 @@ # Calibre-Web -Calibre-Web is a web app that browses, reads, and downloads eBooks from an existing Calibre library database. It is the web frontend for the Calibre e-book manager. +Calibre-Web is a web application that browses, reads, and downloads eBooks from an existing Calibre library database. It serves as the web frontend for the Calibre e-book manager. **Host:** Dankserver — **Hostname:** `books.dankserver.local` — **Docs:** https://github.com/linuxserver/docker-calibre-web -## Facts (from research, primary source) +## Facts | Item | Value | |------|-------| -| Image | `lscr.io/linuxserver/calibre-web:latest` (already running on Dankserver) | +| Latest version | 0.6.27-ls397 | +| Image | `lscr.io/linuxserver/calibre-web:0.6.27-ls397` | +| Base OS | Ubuntu Noble (24.04 LTS, since 2024-12-05) | | Port | 8083 (host) → 8083 (container) | -| Env | `PUID=1000`, `PGID=1000`, `TZ=Etc/UTC` | -| Optional | `DOCKER_MODS=linuxserver/mods:universal-calibre` (ebook conversion, x86-64 only) | -| Volumes | `/config` (internal db + config), `/books` (existing Calibre library) | -| Extra tools | `unrar` (path `/usr/bin/unrar`), `kepubify` (path `/usr/bin/kepubify`) | +| Default login | `admin` / `admin123` | +| Docker mod | `linuxserver/mods:universal-calibre` (ebook conversion, x86-64 only) | +| Volumes | `/config` (internal database + config), `/books` (existing Calibre library) | +| Extra tools | `unrar` at `/usr/bin/unrar`, `kepubify` at `/usr/bin/kepubify` (pre-configured since 2025-01-07) | + +## CVEs Fixed in Latest Version + +| CVE | Issue | +|-----|-------| +| CVE-2025-7404 | External binary names (e.g. `unrar`) restricted to prevent RCE | +| — | XSS in book comments imported via Calibre, now sanitized | + +Additional packages added: `libxfixes3` and `libasound2t64` to support epub-to-pdf conversion. The `--no-sandbox` flag is applied to qtwebengine to prevent crashes in Docker. ## Configuration -- Set the library path in the Calibre-Web admin page: Basic Configuration → Calibre Database → Location of Calibre database = `/books`. -- Set the external binary paths in Basic Configuration → External Binaries after first login. -- The default login is `admin` / `admin123` on first boot; change it immediately. +### Environment Variables + +| Variable | Value | Description | +|----------|-------|-------------| +| `PUID` | `1000` | User ID | +| `PGID` | `1000` | Group ID | +| `TZ` | `Etc/UTC` | Timezone | +| `DOCKER_MODS` | `linuxserver/mods:universal-calibre` | Optional: enables ebook conversion tools | +| `OAUTHLIB_RELAX_TOKEN_SCOPE` | `1` | Required for Google OAuth | + +### Setup Steps + +1. Point the container at the Calibre library directory (set the `/books` volume). +2. Log in with `admin` / `admin123` and change the password immediately. +3. In Basic Configuration → Calibre Database → set Location of Calibre database to `/books`. +4. In Basic Configuration → External Binaries → set the directory to `/usr/bin/` for Calibre-Web >= 0.6.22. +5. **kepubify is pre-configured** since version 0.6.27. No need to set the kepubify path manually. +6. Set up Google OAuth if desired (requires `OAUTHLIB_RELAX_TOKEN_SCOPE=1`). ## Volumes | Container path | Host path (convention) | |----------------|------------------------| | `/config` | `/opt/calibre-web/config` | -| `/books` | the existing Calibre library directory (user-entered later) | +| `/books` | The existing Calibre library directory (user-entered during setup) | -## Healthcheck +## Docker Compose -The web UI responds on 8083. A `wget -q --spider` check on `/` suffices. +```yaml +services: + calibre-web: + image: lscr.io/linuxserver/calibre-web:0.6.27-ls397 + container_name: calibre-web + restart: unless-stopped + environment: + PUID: "1000" + PGID: "1000" + TZ: Etc/UTC + OAUTHLIB_RELAX_TOKEN_SCOPE: "1" + ports: + - "8083:8083" + volumes: + - /opt/calibre-web/config:/config + - /opt/calibre-web/books:/books + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8083/"] + interval: 30s + timeout: 10s + retries: 3 +``` ## Gotchas -- If the DB path is wrong, login appears to succeed but the library is empty. -- Ebook conversion needs the `universal-calibre` mod AND the external binary path set to `/usr/bin/ebook-convert` (or `/usr/bin/` on newer versions). -- Google OAuth needs `OAUTHLIB_RELAX_TOKEN_SCOPE=1`. +- **Wrong database path:** Login appears to succeed but the library is empty. Verify the Calibre database path in the admin page. +- **Ebook conversion:** Requires the `universal-calibre` Docker mod AND the external binary path set to `/usr/bin/` (directory, not full path to `ebook-convert`). +- **Google OAuth:** Set `OAUTHLIB_RELAX_TOKEN_SCOPE=1` or OAuth login fails. +- **calibre 9.9.0 content server security fix:** A bug since v6.16.0 allows any user with server access to read non-Calibre files on the host. Upgrade to 9.9.0+ if serving content to untrusted users. ## See Also - [[Dankserver Stack]] - [[Calibre]] — the underlying library engine (host tool, not a container) +- [[ARR-Stack]] — Readarr for automatic ebook downloads into the Calibre library diff --git a/docs/Dankserver/Calibre.md b/docs/Dankserver/Calibre.md index d184c48..90fcc0b 100644 --- a/docs/Dankserver/Calibre.md +++ b/docs/Dankserver/Calibre.md @@ -1,27 +1,69 @@ # Calibre -Calibre is the e-book library manager behind Calibre-Web. It manages metadata, formats, and conversions for the library that Calibre-Web serves. +Calibre is the e-book library manager that backs Calibre-Web. It manages metadata, formats, and conversions for the library that Calibre-Web serves. **Host:** Dankserver (library directory on host) — **Docs:** https://calibre-ebook.com -## Role in this stack +## Role in this Stack Calibre itself is a desktop/GUI application, not a container service. This stack runs **Calibre-Web** in a container and points it at an existing Calibre library directory on the Dankserver host. -## Library Directory +Calibre is used to: +- Import books into the library (drag-and-drop or CLI `calibredb`) +- Edit metadata (author, title, series, tags, cover art) +- Convert between formats (EPUB → MOBI, MOBI → EPUB, etc.) +- Manage collections and reading lists -The user will enter the existing Calibre library path during Calibre-Web setup. The convention in this repo: +The actual library files (`.epub`, `.mobi`, `.pdf`) and the Calibre database (`.db` file) live on the host filesystem. Calibre-Web reads and writes them through the mounted volume. + +## Current Version + +Calibre 9.9.0 is the latest stable release. Major features include: +- Bookshelf view +- Opt-in AI features +- Content server security fix (CVE-2025-7404 equivalent): a bug since v6.16.0 allows any user with server access to read non-Calibre files on the host. Upgrade to 9.9.0+ if serving content to untrusted users. + +## Library Directory | Purpose | Host path (convention) | |---------|------------------------| -| Calibre library | `/opt/calibre-web/books` (bind-mounted to `/books` in the container) | +| Calibre library | `/opt/calibre-web/books` (bind-mounted to `/books` in the Calibre-Web container) | -## What the container needs +## What the Container Needs -- Read/write access to the library directory (Calibre-Web edits metadata through the app). +- Read/write access to the library directory. Calibre-Web edits metadata through the database file. - Ownership matching `PUID=1000` / `PGID=1000` (the `dank` user on Dankserver). +## Optional: Calibre Content Server + +Calibre includes a built-in HTTP content server (`calibre-server`) that can serve the library via OPDS feeds and a mobile-friendly web interface. This enables: +- OPDS feeds for mobile reading apps (FBReader, Moon+ Reader) +- Mobile-optimized UI via the `--mobile` flag +- Direct Kindle push + +To run as a container: + +```yaml +services: + calibre-server: + image: lscr.io/linuxserver/calibre:latest + container_name: calibre-server + restart: unless-stopped + environment: + PUID: "1000" + PGID: "1000" + TZ: Etc/UTC + command: calibre-server --daemonize --port 8080 --enable-auth --url-prefix /calibre /books + volumes: + - /opt/calibre-web/books:/books + ports: + - "8084:8080" +``` + +Note: The content server runs headless in `--daemonize` mode. It requires the full Calibre package, not a minimal server. + ## See Also - [[Calibre-Web]] — the containerized frontend - [[Dankserver Stack]] +- [[ARR-Stack]] — Readarr for automatic ebook downloads diff --git a/docs/Dankserver/Copyparty.md b/docs/Dankserver/Copyparty.md index 69bf243..207598e 100644 --- a/docs/Dankserver/Copyparty.md +++ b/docs/Dankserver/Copyparty.md @@ -1,25 +1,49 @@ # Copyparty -Copyparty is a lightweight file server that shares and streams files over HTTP. It handles large payloads, media streaming, uploads, and directory browsing from a single Python binary. +Copyparty is a lightweight file server and media streamer that runs as a single Python binary. It handles large payloads, media streaming, resumable uploads, directory browsing, and WebDAV from one process. **Host:** Dankserver — **Hostname:** `files.dankserver.local` — **Docs:** https://github.com/9001/copyparty -## Facts (from research) +## Facts | Item | Value | |------|-------| +| Latest version | v1.20.19 (released 2026-07-27) | | Image | `ghcr.io/9001/copyparty:latest` (official Dockerfile in repo) | | Port | 3923 (host) → 3923 (container) | | Volume | bind mount the shared root directory | -| Auth | per-directory `.cpy` config files, HTTP basic auth | -| Streaming | HTTP range requests, HLS, WebDAV | +| Auth | Per-directory `.cpy` config files, HTTP basic auth, `dirkeys`, `filekeys` | +| Streaming | HTTP range requests, HLS, WebDAV, WOPI (Office editing) | +| Docker editions | `dj` (document + media), `iv` (image + video), `v` (video only) | ## Configuration -- Run with `-e COPAY_PASS=...` or configure per-folder passwords. -- Set `-e COPAY_MODE=rw` for read-write shares where uploads are allowed. -- The container publishes port 3923; expose it to Caddy only, not the WAN. -- `--resumable` enables resumable uploads for large files (models, ISOs). +### Environment Variables + +| Variable | Description | +|----------|-------------| +| `COPAY_PASS` | Master password for the web UI | +| `COPAY_MODE` | Set to `rw` for read-write shares | + +### Configuration File Options + +Copyparty reads its configuration from `initcfg` (or `config` in the `/data` directory). Key options: + +- `use-bwrap: n` — Disable bwrap sandboxing for ffmpeg (default in Docker). Set to `y` to enable. +- `shadowing //NULL` — Full unmap of a volume from the filesystem. +- Config env-var expansion: Use `${VAR}` syntax in `[global]` section for environment variable substitution. + +### Docker Editions + +Different editions bundle different libraries: + +| Edition | Bundled Libraries | Use Case | +|---------|-------------------|----------| +| `dj` | Document + image + video libraries | Full-featured server | +| `iv` | Image + video libraries | Image and video focused | +| `v` | Video only | Transcoding only, minimal footprint | + +The `iv` edition is no longer available for arm32/armv6. Use `dj` for maximum compatibility. ## Volumes @@ -27,17 +51,56 @@ Copyparty is a lightweight file server that shares and streams files over HTTP. |----------------|------------------------| | `/data` | `/opt/copyparty/data` | +## Docker Compose + +```yaml +services: + copyparty: + image: ghcr.io/9001/copyparty:latest + container_name: copyparty + restart: unless-stopped + environment: + COPAY_PASS: "${COPAY_PASS}" + COPAY_MODE: rw + ports: + - "3923:3923" + volumes: + - /opt/copyparty/data:/data + healthcheck: + test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3923/')"] + interval: 30s + timeout: 10s + retries: 3 +``` + ## Healthcheck -A simple TCP check on 3923 works; Copyparty returns HTTP 200 on the web root. +A simple HTTP check on port 3923 works. The root path returns HTTP 200 with the directory listing. + +## WOPI Integration + +Copyparty v1.20.9+ supports WOPI (Web Application Open Platform Interface) for editing Office documents in the web UI via Collabora Online. Enable with the `--wopi-accs` flag to limit WOPI access to specific paths. + +## Security Advisories + +| Version | CVE | Issue | +|---------|-----|-------| +| v1.20.19 | GHSA-phv8-wgjp-g4p9 | FTP upload outside volume | +| v1.20.17 | GHSA-x5pq-m9p8-f4vx | dirkey/filekey confusion | +| v1.20.9 | CVE-2026-27948 / GHSA-62cr-6wp5-q43h | XSS via file upload | + +Upgrade to v1.20.19+ to cover all known CVEs. The dirkey fix (v1.20.17) matters if using both `dirkeys` and `filekeys`. ## Gotchas -- Large transfers benefit from disabling TLS inside the app and letting Caddy terminate TLS. -- Do not give Copyparty the whole disk; give it a dedicated share directory. -- Upload tokens scoped per folder prevent accidental global write access. +- **Large transfers:** Disable TLS inside the app and let Caddy terminate TLS. This avoids double encryption overhead. +- **Dedicated share directory:** Do not give Copyparty the whole disk. Mount only the intended share path. +- **Upload tokens scoped per folder:** Prevents accidental global write access. +- **CSP nonces (v1.20.17+):** Security hardening for JavaScript execution. May break third-party JS plugins (`--js-browser` / `--html-head`). +- **Custom thumbnail extractors (v1.20.19+):** New `thumbex` framework. Requires configuration in `initcfg`. ## See Also - [[Dankserver Stack]] -- [[Caddy]] — TLS termination and auth in front +- [[Caddy]] — TLS termination and authentication in front +- [[ARR-Stack]] — Copyparty as a viewer alongside automated download management diff --git a/docs/Dankserver/Dankserver Stack.md b/docs/Dankserver/Dankserver Stack.md index 9743097..affe2fa 100644 --- a/docs/Dankserver/Dankserver Stack.md +++ b/docs/Dankserver/Dankserver Stack.md @@ -8,7 +8,13 @@ graph LR C --> R[RomM] C --> P[Copyparty] C --> W[Calibre-Web] - W --> L[Calibre library] + C --> J[Jellyfin] + C --> S[Sonarr] + C --> D[Radarr] + C --> L[Lidarr] + C --> A[Readarr] + C --> O[Prowlarr] + W --> L2[Calibre library] ``` ## Services @@ -18,6 +24,22 @@ graph LR | RomM | romm.dankserver.local | 8085 | [[RomM]] | | Copyparty | files.dankserver.local | 3923 | [[Copyparty]] | | Calibre-Web | books.dankserver.local | 8083 | [[Calibre-Web]] | +| Jellyfin | jellyfin.dankserver.local | 8096 | [[Jellyfin]] | +| Sonarr | sonarr.dankserver.local | 8989 | [[ARR-Stack]] | +| Radarr | radarr.dankserver.local | 7878 | [[ARR-Stack]] | +| Lidarr | lidarr.dankserver.local | 8686 | [[ARR-Stack]] | +| Readarr | readarr.dankserver.local | 8787 | [[ARR-Stack]] | +| Prowlarr | prowlarr.dankserver.local | 9696 | [[ARR-Stack]] | +| qBittorrent | qbittorrent.dankserver.local | 8080 | [[ARR-Stack]] | + +## Optional Services + +These services are included in the compose file but may be disabled. + +| Service | Hostname | Port | Docs | +|---------|----------|------|------| +| Jackett | jackett.dankserver.local | 9117 | [[ARR-Stack]] | +| Whisparr | whisparr.dankserver.local | 6969 | [[ARR-Stack]] | ## Removed Services diff --git a/docs/Dankserver/Jellyfin.md b/docs/Dankserver/Jellyfin.md new file mode 100644 index 0000000..d3f96e8 --- /dev/null +++ b/docs/Dankserver/Jellyfin.md @@ -0,0 +1,173 @@ +# Jellyfin + +Jellyfin is a free, open-source media server and suite of applications for organizing, managing, and streaming personal media collections (movies, TV shows, music, photos) to networked devices. It is a community fork of Emby, written in C# (.NET), and uses FFmpeg for transcoding. + +**Host:** Dankserver — **Hostname:** `jellyfin.dankserver.local` — **Docs:** https://jellyfin.org + +## Facts + +| Item | Value | +|------|-------| +| Latest version | Check https://jellyfin.org/downloads | +| Image | `jellyfin/jellyfin:latest` (Docker Hub) or `ghcr.io/jellyfin/jellyfin` | +| Base | Debian-based | +| Primary port | 8096 (HTTP, web UI + API) | +| HTTPS port | 8920 (optional) | +| Client discovery | 7359/udp | +| DLNA | 1900/udp (optional) | +| GPU passthrough | `/dev/dri` (Intel QSV / AMD VA-API) or NVIDIA NVENC | +| License | MIT | + +## Architecture + +```mermaid +graph LR + U[User] --> C[Caddy :80/:443] + C --> J[Jellyfin :8096] + J --> Lib[/media/movies] + J --> Lib2[/media/shows] + J --> Lib3[/media/music] + J --> Conf[Jellyfin config] + J --> Cache[Jellyfin cache] +``` + +## Docker Compose + +```yaml +services: + jellyfin: + image: jellyfin/jellyfin:latest + container_name: jellyfin + restart: unless-stopped + user: "1000:1000" + ports: + - "8096:8096/tcp" + - "8920:8920/tcp" + - "7359:7359/udp" + - "1900:1900/udp" + environment: + - JELLYFIN_PublishedServerUrl=http://192.168.0.235:8096 + - DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true + volumes: + - /opt/jellyfin/config:/config + - /opt/jellyfin/cache:/cache + - /mnt/media/movies:/data/movies:ro + - /mnt/media/shows:/data/shows:ro + devices: + - /dev/dri:/dev/dri + group_add: + - "992" # Host render group GID — verify with `getent group render` + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8096/health"] + interval: 30s + timeout: 10s + retries: 3 +``` + +## Caddy Configuration + +```caddy +jellyfin.dankserver.local { + reverse_proxy 127.0.0.1:8096 + + transport http { + versions h2c 1.1 + } +} +``` + +Set **Base URL** to `/` (or the path you configure) in Jellyfin Dashboard → Networking. Add `127.0.0.1` to **Known Proxies**. + +## Storage + +| Mount | Purpose | Size Estimate | +|-------|---------|---------------| +| `/opt/jellyfin/config` | SQLite database, settings, cached images | 10–100 GB | +| `/opt/jellyfin/cache` | Transcoding segments, extracted posters | Self-cleaning per session | + +The database must be on local storage (SSD/NVMe preferred). Media libraries can be on NFS/mergerfs. If media is on NFS, set `DOTNET_SYSTEM_IO_DISABLEFILELOCKING=true`. + +## Authentication + +- **Built-in auth (default):** Per-user libraries, parental controls, max bitrate limits. Manage via Dashboard → Users. +- **Caddy basic auth:** Single login layer. Does not integrate with per-user Jellyfin permissions. +- **LDAP/OIDC:** Available via plugins (LDAP-Auth, Jellyfin SSO). Integrates with Authentik, Keycloak, etc. + +For Dankserver, built-in auth is recommended. Use Caddy basic auth on top for external access. + +## Metadata Scraping + +| Provider | Content | Type | +|----------|---------|------| +| TheMovieDb (TMDb) | Movies, TV shows, posters, fan art, overviews | Default | +| OMDb API | Movies only, English metadata | Default | +| TheTVDB | TV shows, episodes | Plugin | +| fanart.tv | Extra artwork, banners, thumbnails | Plugin | +| AniDB | Anime metadata | Plugin | +| MusicBrainz | Music metadata | Plugin | +| Open Subtitles | Subtitle downloads | Plugin | +| Intro Skipper | TV show intro detection | Plugin | + +## Clients + +| Platform | App | Quality | +|----------|-----|---------| +| Web | Jellyfin Web | Excellent | +| Android | Jellyfin (Google Play / F-Droid) | Excellent | +| Android TV / Fire TV | Jellyfin | Good | +| iOS / iPadOS | Swiftfin (third-party) | Good | +| Desktop | Jellyfin Media Player (mpv-based) | Excellent | +| Roku | Jellyfin (Channel Store) | Good | +| Kodi | Jellyfin addon | Excellent | +| Samsung/LG Smart TVs | TV browser | Fair | + +## Jellyfin vs Plex + +| Feature | Jellyfin | Plex | +|---------|----------|------| +| Cost | Free, no tiers | Free core; Plex Pass ($5/mo or $120 lifetime) | +| License | MIT | Proprietary | +| Account required | No | Yes | +| Hardware transcoding | Free | Plex Pass required | +| Mobile sync | Free | Plex Pass | +| Live TV / DVR | Free | Plex Pass | +| Client apps | Good, improving | Excellent, widest device support | + +Run Jellyfin alongside Plex for an incremental migration. Point Jellyfin at the same media folders as Plex. Watch history and metadata will not transfer cleanly. + +## Resource Requirements + +- **Idle / Direct Play:** ~200–500 MB RAM, <5% CPU. Negligible. +- **1080p transcode (CPU):** 40–60% CPU on a modern multi-core CPU. +- **1080p transcode (with QSV):** 3–5% CPU. +- **4K HDR transcode (with QSV):** 5–15% CPU. +- **Minimum host RAM:** 4 GB. 8 GB comfortable for transcoding. + +## Deployment Checklist + +1. Verify GPU on host: `ls -l /dev/dri/`, `lspci | grep -i vga`, `getent group render`. +2. Install media drivers: `sudo apt install intel-media-va-driver-non-free vainfo intel-gpu-tools`. +3. Create directories: `/opt/jellyfin/config`, `/opt/jellyfin/cache`. +4. Write compose file, verify device and GID. +5. Deploy: `podman compose up -d`. +6. Test GPU passthrough: `podman exec jellyfin /usr/lib/jellyfin-ffmpeg/vainfo --display drm --device /dev/dri/renderD128`. +7. Configure Caddy reverse proxy. Set Known Proxies in Jellyfin. +8. Add media libraries in Dashboard. +9. Install plugins: Open Subtitles, fanart.tv, Intro Skipper. +10. Test playback on Android/Chrome. + +## Gotchas + +- **GPU passthrough silently failing:** `/dev/dri` must be passed and the correct render node used. Verify with `vainfo` inside the container. +- **Wrong render group GID:** Common GID is 992, but varies per host. Run `getent group render` to find it. +- **Subtitle burn-in triggers full transcode:** PGS (image-based) subtitles force full video transcoding. SRT/ASS (text-based) play fine. +- **Database on NFS:** SQLite on network storage causes slow startup and corruption risk. Keep `/config` on local storage. +- **Client bitrate limit too low:** Many clients default to 20 Mbps. Set Max Streaming Bitrate to Original or Maximum. +- **Naming convention mismatches:** Non-standard folder/file names cause missing metadata. Use `Movie Title (Year)` for movies and `Show Name/Season 01/Show Name S01E01.mkv` for TV. + +## See Also + +- [[Dankserver Stack]] +- [[ARR-Stack]] — automated download into Jellyfin libraries +- [[Copyparty]] — alternative file viewer for existing collections +- [[Plex]] — existing media server on this host diff --git a/docs/Dankserver/RomM-Scraping.md b/docs/Dankserver/RomM-Scraping.md new file mode 100644 index 0000000..855d0af --- /dev/null +++ b/docs/Dankserver/RomM-Scraping.md @@ -0,0 +1,296 @@ +# RomM Scraping & Asset Management + +This guide covers metadata providers, cover art, ROM naming conventions, emulator integration, and the scraping workflow for RomM on Dankserver. + +**Reference:** https://docs.romm.app + +## 1. Metadata Providers + +RomM v5.1.0+ supports 11+ metadata providers. The `scan.priority.metadata` list determines which provider wins for descriptive fields. The `scan.priority.artwork` list controls cover art sourcing separately. + +### Screenscraper (ScreenScraper.fr) + +- **Type:** Free, community-driven (French provider) +- **Credentials:** `SCREENSCRAPER_USER` + `SCREENSCRAPER_PASSWORD` (account user/pass) +- **Registration:** https://www.screenscraper.fr/membreinscription.php +- **Rate limits:** No documented hard cap. Community-claimed ~5 req/sec burst. +- **Capabilities:** Titles, descriptions, cover art, screenshots, manuals, 3D boxes, CD/cartridge covers, marquee logos, fanart, bezels, gameplay videos. +- **Region support:** Excellent. Respects `scan.priority.region` and `scan.priority.region_mode`. +- **Best for:** Richest media coverage (all art types), multi-platform, free. Use as secondary to IGDB for metadata, or swap priority order if Screenscraper art quality is preferred. + +### IGDB (Internet Game Database / Twitch) + +- **Type:** Freemium (free tier with limits; paid for higher volume) +- **Credentials:** `IGDB_CLIENT_ID` + `IGDB_CLIENT_SECRET` (Twitch OAuth2) +- **Registration:** Twitch Developer Portal. Create app with name `romm-`, OAuth redirect `localhost`, category `Application Integration`, client type `Confidential`. +- **Rate limits:** ~10 req/sec for free tier. Cached responses reduce effective calls. +- **Capabilities:** Titles, descriptions, cover art, screenshots, related games, release dates, genres, platforms. +- **Limitations:** No 3D boxes or physical media art. No manuals. No marquee/fanart. +- **Default priority:** Highest (`igdb` listed first in both metadata and artwork priority). + +### MobyGames + +- **Type:** Paid (hobbyist API subscription; non-commercial use only) +- **Credentials:** `MOBYGAMES_API_KEY` +- **Rate limits:** Hobbyist tier ~0.2 req/sec (one request every 5 seconds). +- **RomM recommendation:** "We recommend using ScreenScraper instead, as it is free to use." +- **Best for:** Supplemental metadata depth for older PC/console titles. + +### RetroAchievements (RAHasher) + +- **Type:** Free, hash-based achievement tracking +- **Credentials:** `RETROACHIEVEMENTS_API_KEY` +- **How it works:** RomM bundles RAHasher (v1.8.3+). ROMs are hashed during scans, matched against RA online database. Achievement progress synced per-user via their RA username. +- **Known issues:** Folder-based disc ROMs (`.cue` + `.bin`, `.gdi`) may fail hashing. Non-zip archives (`.7z`, `.rar`) had incorrect hash computation. Ensure `filesystem.skip_hash_calculation` is `false`. +- **Important:** Achievements cannot be earned via RomM's built-in EmulatorJS player. Must use an RA-capable standalone emulator. + +### Additional Built-in Providers + +| Provider | Slug | Enabled Via | Type | +|----------|------|-------------|------| +| Hasheous | `hasheous` | `HASHEOUS_API_ENABLED=true` | Free, hash-based, proxies IGDB data | +| Playmatch | `playmatch` | `PLAYMATCH_API_ENABLED=true` | Multi-provider hash matching | +| LaunchBox | `launchbox` | `LAUNCHBOX_API_ENABLED=true` + XML | Local XML database | +| Flashpoint | `flashpoint` | `FLASHPOINT_API_ENABLED=true` | 180,000+ browser games | +| HowLongToBeat | `hltb` | `HLTB_API_ENABLED=true` | Game completion times | +| SteamGridDB | `steamgriddb` | `STEAMGRIDDB_API_KEY` | Custom cover art | +| ES-DE gamelist | `gamelist` | Place `gamelist.xml` in platform folder | Local XML | + +## 2. Recommended Provider Combinations + +| Combo | Providers | Best For | Cost | +|-------|-----------|----------|------| +| Quick Starter | Hasheous only | No API keys needed | Free | +| French Connection | Screenscraper + RetroAchievements | Rich media, free | Free | +| Chef's Choice (recommended) | Hasheous + IGDB + SteamGridDB + RetroAchievements | Best overall quality | Free (IGDB free tier) | +| Twitch Fanboy | IGDB + Playmatch | Single-provider solution | Free | + +**For Dankserver,** the recommended setup: +- `IGDB` (primary metadata) + `SCREENSCRAPER` (artwork backup + rich media) + `RETROACHIEVEMENTS` (achievements) + `HASHEOUS_API_ENABLED=true` (fast hash-based fallback) + +## 3. ROM File Naming Conventions + +### No-Intro Naming Scheme (Recommended) + +The de facto standard for cartridge and handheld ROMs. Only `Title` and `Region` are required. + +``` +Super Metroid (Japan, USA) (En,Ja) +Sonic the Hedgehog (USA) +Metal Gear Solid (USA) (Disc 1) +[BIOS] PS1 System BIOS (USA) +Tetris [!].gba +``` + +**Field meanings:** +- `(Region)`: `USA`, `EUR`, `JPN`, `UE` (USA+Europe), `JUE` (Japan+USA+Europe) +- `(Languages)`: `En`, `Ja`, `De`, `Fr`, `Es` +- `[Status]`: `[!]` = verified good dump, `[b]` = bad dump, `[c]` = completed +- `(Devstatus)`: `(Proto)`, `(Demo)`, `(Release Candidate)` +- `[BIOS]` prefix: Identifies BIOS files + +### RomM's Region/Language/Revision Parsing + +RomM parses inline tags from filenames: + +``` +tetris (En) [1.0001] [HACK] [!].gba +``` + +- Region/language: ISO-like codes or full names +- Revision: `rev v1` or `rev-1` +- Provider ID tags: `(igdb-xxxx)`, `(ssfr-xxxx)`, `(moby-xxxx)`, `(ra-xxxx)` — forces specific provider match + +### Best Practices for Dankserver + +1. Use No-Intro naming as the standard. +2. Use **Igir** to rename and organize ROMs into RomM's required folder structure: + ``` + igir copy zip test clean \ + --dat "No-Intro*.zip" \ + --input "ROMs" \ + --output "/opt/romm/roms/{romm}" + ``` +3. Keep `[BIOS]` prefix for BIOS files in the `bios/` directory. +4. One ROM file per game folder where possible. +5. Use archive formats (`.zip`, `.7z`) — RomM supports them natively. + +## 4. Cover Art & Media Assets + +### Media Types + +| Media Type | Description | Best Provider | +|-----------|-------------|---------------| +| `box2d` | Standard 2D front cover art | IGDB, Screenscraper | +| `box3d` | 3D box art | Screenscraper | +| `miximage` | Composite (box + screenshot + logo) | Screenscraper | +| `screenshot` | In-game screenshot | IGDB, Screenscraper | +| `marquee` | Transparent logo/header | Screenscraper | +| `bezel` | EmulatorJS-compatible bezel | Screenscraper | +| `manual` | PDF instruction manual | Screenscraper | +| `video` | Gameplay video/trailer | Screenscraper | + +### Custom Artwork Directories + +RomM supports manual artwork placement via subdirectories within each game folder: + +``` +/opt/romm/library/roms/{platform}/{game}/ + game.rom + covers/ + screenshots/ + 3dboxes/ + manuals/ + fanart/ + videos/ + marquees/ + bezels/ +``` + +For ES-DE gamelist imports, media maps as: + +| gamelist.xml Tag | Folder Name | +|-----------------|-------------| +| `` | `covers/` | +| `` | `backcovers/` | +| `` | `3dboxes/` | +| `` | `marquees/` | +| `` | `screenshots/` | +| `` | `fanart/` | +| `` | `manuals/` | + +### MAME Artwork + +MAME uses cabinet pics, flyers, marquees, control panels, backdrops, overlays. Stored in `{platform}/mame_artwork/{game}/` subdirectories. + +Sources: Mr. Do's Arcade (https://www.mameworld.info/mrdo/), ProgettoSnaps (http://www.progettosnaps.net/artworks/). + +## 5. Emulator Integration + +### EmulatorJS (Built-in) + +Web-based player using RetroArch cores compiled to WebAssembly. Runs in-browser with no local emulator needed. Configured via `emulatorjs.*` settings in `config.yml`. Supports netplay via STUN/TURN servers. + +### Emulator Streaming + +Launch native emulator containers (PCSX2, Dolphin, Xemu) and stream picture/sound/input back to the browser. Configured via `streaming.*` in `config.yml`. + +### BIOS File Requirements + +BIOS files placed in `/opt/romm/library/bios/{platform}/`. Platform subdirectories required. File names should match emulator expectations: + +| Platform | BIOS File | +|----------|-----------| +| PlayStation | `scph1001.bin`, `scph5501.bin`, `scph5502.bin` | +| GB/GBC | `gb_bios.bin`, `gbc_bios.bin` | +| SNES | `sfc_bios.bin` | + +BIOS matching done by hash against platform requirements. + +### Folder Structure Options + +**Structure A (recommended):** +``` +/opt/romm/library/ + roms/ + └── {platform}/ + └── {game}.rom + bios/ + └── {platform}/ + └── {bios_file}.bin +``` + +**Structure B (fallback):** +``` +/opt/romm/library/ + └── {platform}/ + ├── roms/ + │ └── {game}.rom + └── bios/ + └── {bios_file}.bin +``` + +Dankserver mounts `/opt/romm/library:/romm/library` — RomM auto-detects structure. + +## 6. Scraping Workflow + +### Recommended Pipeline + +1. Organize ROMs → No-Intro naming + RomM folder structure. +2. Create `config.yml` → Set provider credentials, priority lists, region prefs. +3. First scan → Scan ALL → verify everything is matched. +4. Review unmatched → Manually match or add provider tags to filenames. +5. Fetch artwork → Re-scan with `scan.media` extended to desired types. +6. Sync RetroAchievements → Set user RA username → trigger sync. +7. Export gamelist → Enable `scan.gamelist.export` for ES-DE/Batocera. +8. Maintain → Enable scheduled rescans for new DAT updates. + +### Scan Types + +| Scan Type | What It Does | +|-----------|-------------| +| ALL | Full scan — hash, match metadata, fetch artwork | +| UNMATCHED | Only matches unmatched ROMs (faster) | +| METADATA | Updates metadata only | +| ARTWORK | Re-fetches artwork only | +| RETROACHIEVEMENTS | Syncs achievement data | + +### Region Handling + +```yaml +scan: + priority: + region: + - "us" + - "eu" + - "jp" + region_mode: prefer_rom_tags # or prefer_config +``` + +- `prefer_rom_tags` (default): ROM filename region tags take precedence. +- `prefer_config`: Config regions come first. +- **NTSC-U** (USA): 60 Hz, typically fastest, most translations. +- **PAL** (Europe): 50 Hz, sometimes slower, may have bonus content. +- **NTSC-J** (Japan): 60 Hz, Japanese only unless region-patched. + +## 7. Collection Management Tools + +| Tool | Primary Role | Platform | +|------|-------------|----------| +| RomVault 3.7.6 | DAT-file-based verification and reorganization | Windows | +| clrMAMEPro | ROM set validation, deduplication, 1G1R | Windows | +| DATBios | BIOS file organization using DAT files | Windows | +| Batocera/Lakka integration | ES-DE gamelist import from RomM | Linux/ARM | + +## 8. Environment Variables (Dankserver) + +```bash +# Auth +ROMM_USERNAME=admin +ROMM_PASSWORD= +ROMM_AUTH_SECRET_KEY=$(openssl rand -hex 32) + +# Metadata Providers +IGDB_CLIENT_ID= +IGDB_CLIENT_SECRET= +SCREENSCRAPER_USER= +SCREENSCRAPER_PASSWORD= +MOBYGAMES_API_KEY= +RETROACHIEVEMENTS_API_KEY= +STEAMGRIDDB_API_KEY= + +# Feature Flags +HASHEOUS_API_ENABLED=true +PLAYMATCH_API_ENABLED=true + +# Scanning +ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true +ENABLE_SCHEDULED_RESCAN=true +REFRESH_RETROACHIEVEMENTS_CACHE_DAYS=7 +``` + +## See Also + +- [[RomM]] — main service documentation +- [[Dankserver Stack]] +- [[ARR-Stack]] — Readarr for ebook auto-downloads alongside ROM management diff --git a/docs/Dankserver/RomM.md b/docs/Dankserver/RomM.md index 7c39eff..b155887 100644 --- a/docs/Dankserver/RomM.md +++ b/docs/Dankserver/RomM.md @@ -1,26 +1,103 @@ # RomM -RomM (ROM Manager) is a self-hosted rom manager and player for retro game collections. It scans a ROM library, enriches it with metadata and cover art, and serves it through a clean web UI. +RomM (ROM Manager) is a self-hosted ROM library manager and player. It scans a ROM collection, enriches it with metadata and cover art from multiple providers, and serves it through a clean web interface. RomM also supports browser-based emulation via EmulatorJS and native emulator streaming. **Host:** Dankserver — **Hostname:** `romm.dankserver.local` — **Docs:** https://docs.romm.app -## Facts (from research) +## Facts | Item | Value | |------|-------| +| Latest version | 5.2.0 (released 2026-07-29) | | Image | `ghcr.io/rommapp/romm:latest` | | Port | 8085 (host) → 8080 (container) | -| Data volume | config, cache, covers, metadata DB | -| ROMs volume | bind mount to the game library | -| Frontend | React; backend FastAPI/Node | -| Metadata | Screenscraper, IGDB, MobyGames, RAHasher (optional) | +| Database | MariaDB (default); PostgreSQL optional | +| Cache / Queue | Redis or Valkey (required for task queue) | +| Frontend | React SPA | +| Backend | FastAPI / Node | +| Metadata providers | IGDB, Screenscraper, MobyGames, Hasheous, Playmatch, LaunchBox, Flashpoint, HowLongToBeat, SteamGridDB, RetroAchievements, TGDB, ES-DE gamelist | +| Emulator player | EmulatorJS (WebAssembly RetroArch cores) | +| Emulator streaming | Native containers (PCSX2, Dolphin, Xemu) → browser | + +## Architecture + +RomM 5.2.0 requires three supporting services. The compose stack includes `romm`, `mariadb`, and `redis` (or `valkey`). + +```mermaid +graph LR + U[User] --> C[Caddy :80/:443] + C --> R[RomM :8085] + R --> DB[(MariaDB)] + R --> Cache[(Redis)] + R --> Lib[/romm/library] + R --> Res[/romm/resources] +``` ## Configuration -- Set `ROMM_USERNAME`, `ROMM_PASSWORD`, `ROMM_SECRET_KEY` on first boot (creates the admin user). -- `DISABLE_AUTH: true` disables authentication for LAN-only deployments (not recommended behind Caddy auth). -- Bind-mount the ROM library read-only unless RomM should also manage folder structure. -- Metadata providers need API keys; set them in the RomM admin UI after first login. +### Environment Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| `ROMM_USERNAME` | Yes | Initial admin username | +| `ROMM_PASSWORD` | Yes | Initial admin password (set on first boot) | +| `ROMM_AUTH_SECRET_KEY` | Yes | JWT signing key. Generate with `openssl rand -hex 32`. Replaces the old `ROMM_SECRET_KEY`. | +| `DB_HOST` | Yes | MariaDB hostname (e.g. `mariadb`) | +| `DB_NAME` | Yes | Database name (e.g. `romm`) | +| `DB_USER` | Yes | Database user | +| `DB_PASSWD` | Yes | Database password | +| `REDIS_HOST` | Yes | Redis hostname (e.g. `redis`) | +| `DISABLE_SETUP_WIZARD` | No | Set to `true` to skip the first-run wizard | +| `OIDC_ENABLED` | No | Enable OpenID Connect authentication | +| `OIDC_CLIENT_ID` | No | OIDC client ID | +| `OIDC_CLIENT_SECRET` | No | OIDC client secret | +| `OIDC_REDIRECT_URI` | No | OIDC redirect URI | +| `STREAMING_BROKER_SECRET` | No | Secret for native emulator streaming | +| `STREAMING_SAVE_TIMEOUT` | No | Timeout for save states during streaming | +| `KIOSK_MODE` | No | Enable kiosk mode | +| `ROMM_SESSION_SECURE_COOKIE` | No | Secure cookie flag for sessions | + +### Metadata Provider Credentials + +These are set via environment variables or in `config.yml`: + +| Variable | Provider | Notes | +|----------|----------|-------| +| `IGDB_CLIENT_ID` / `IGDB_CLIENT_SECRET` | IGDB (Twitch OAuth2) | Create app at Twitch Developer Portal. Free tier: ~10 req/sec. | +| `SCREENSCRAPER_USER` / `SCREENSCRAPER_PASSWORD` | Screenscraper | Account credentials (not API key). Free, community-driven. | +| `MOBYGAMES_API_KEY` | MobyGames | Paid hobbyist API. Note: RomM recommends Screenscraper as free alternative. | +| `RETROACHIEVEMENTS_API_KEY` | RetroAchievements | Hash-based achievements via bundled RAHasher binary. | +| `STEAMGRIDDB_API_KEY` | SteamGridDB | Custom cover art via the search cover button. | +| `HASHEOUS_API_ENABLED` | Hasheous | Set to `true`. Free, hash-based, proxies IGDB data. Fast scans. | +| `PLAYMATCH_API_ENABLED` | Playmatch | Set to `true`. Multi-provider hash matching (IGDB, SS, SteamGridDB, RA). | + +### Config File + +RomM uses `config.yml` for scan settings, available through the admin UI (Scan Settings). Place the file at `/opt/romm/config/config.yml` on the host. + +Key scan config options: + +```yaml +scan: + priority: + metadata: + - igdb + - ss # Screenscraper + artwork: + - igdb + - ss + region: + - us + - eu + - jp + region_mode: prefer_rom_tags # or prefer_config + media: + - box2d + - screenshot + - manual + gamelist: + export: true # Export ES-DE compatible gamelist.xml +``` ## Volumes @@ -28,18 +105,90 @@ RomM (ROM Manager) is a self-hosted rom manager and player for retro game collec |----------------|------------------------| | `/romm/library` | `/opt/romm/library` | | `/romm/resources` | `/opt/romm/resources` | +| `/romm/config` | `/opt/romm/config` | + +The library volume contains ROM files and subdirectories per platform. The resources volume stores cached artwork, metadata, and the SQLite/SQLite-backed asset cache. The config volume holds `config.yml` and other configuration. + +## Docker Compose + +```yaml +services: + romm: + image: ghcr.io/rommapp/romm:latest + container_name: romm + restart: unless-stopped + environment: + ROMM_USERNAME: "${ROMM_USERNAME}" + ROMM_PASSWORD: "${ROMM_PASSWORD}" + ROMM_AUTH_SECRET_KEY: "${ROMM_AUTH_SECRET_KEY}" + DB_HOST: mariadb + DB_NAME: romm + DB_USER: "${ROMM_DB_USER}" + DB_PASSWD: "${ROMM_DB_PASSWD}" + REDIS_HOST: redis + ports: + - "8085:8080" + volumes: + - /opt/romm/library:/romm/library + - /opt/romm/resources:/romm/resources + - /opt/romm/config:/romm/config + depends_on: + mariadb: + condition: service_healthy + redis: + condition: service_healthy + + mariadb: + image: docker.io/mariadb:11 + container_name: romm-mariadb + restart: unless-stopped + environment: + MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}" + MARIADB_DATABASE: romm + MARIADB_USER: "${ROMM_DB_USER}" + MARIADB_PASSWORD: "${ROMM_DB_PASSWD}" + volumes: + - /opt/romm/mariadb:/var/lib/mysql + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 3 + + redis: + image: docker.io/redis:7-alpine + container_name: romm-redis + restart: unless-stopped + volumes: + - /opt/romm/redis:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 3 +``` ## Healthcheck -Expose a `/health` endpoint; RomM serves the UI on `/`. +```yaml +healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 +``` ## Gotchas -- The first login sets the admin password; do not rely on the env credentials after that. -- Database is SQLite by default — back it up with the resources volume. -- RAHasher build increases image build time; skip unless RetroAchievements hashes are needed. +- **First login overwrites env credentials.** The `ROMM_PASSWORD` env var sets the initial password. After first login, the admin password is controlled in the UI. The env var only applies on first boot. +- **MariaDB and Redis are required.** RomM 5.2.0 no longer supports SQLite-only deployments. Both MariaDB and Redis must be running. +- **Reverse proxy cache stale index.html.** Purge Caddy proxy cache after RomM version bumps to avoid serving a stale frontend after an upgrade. +- **RAHasher build time.** Enabling RetroAchievements hashing increases the first image build. Skip unless you need achievement data. +- **MobyGames is paid.** The hobbyist API has strict rate limits. Screenscraper is the recommended free alternative. +- **OIDC requires additional services.** Authentik, Keycloak, or another OIDC provider must be running before enabling `OIDC_ENABLED`. ## See Also - [[Dankserver Stack]] +- [[RomM Scraping]] — metadata providers, cover art, naming conventions, emulator integration - [[Calibre-Web]] — sibling library web UI diff --git a/docs/Dankserver/lidarr.md b/docs/Dankserver/lidarr.md new file mode 100644 index 0000000..607224c --- /dev/null +++ b/docs/Dankserver/lidarr.md @@ -0,0 +1,53 @@ +# Lidarr + +Lidarr manages music albums in the *arr stack on Dankserver. It automatically searches, downloads, and organizes albums from indexers into the Jellyfin music library. + +**Host:** Dankserver — **Hostname:** `lidarr.dankserver.local` — **Docs:** https://wiki.servarr.com/lidarr + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/lidarr:latest` | +| Port | 8686 (host) → 8686 (container) | +| Min RAM | 256 MB | +| Metadata | MusicBrainz | + +## Docker Compose + +```yaml +lidarr: + image: lscr.io/linuxserver/lidarr:latest + container_name: lidarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/lidarr/config:/config + - /mnt/media/music:/music + - /mnt/media/downloads:/downloads + ports: + - "8686:8686" + networks: [appnet] +``` + +## Configuration + +1. Add Prowlarr as the indexer source (prefer torrent-based indexers for FLAC). +2. Add qBittorrent as the download client with the `music` category. +3. Set quality profile (Lossless → High Bitrate → Standard). +4. Set root folder to `/music`. +5. Add artists and verify downloads. + +## Gotchas + +- Album variants: Lidarr supports multiple releases of the same album (vinyl vs CD). Use "Preferred" and "Cutoff" quality profiles. +- Music videos can be optionally downloaded separately from albums. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation +- [[Jellyfin]] — media server that consumes Lidarr downloads diff --git a/docs/Dankserver/mariadb.md b/docs/Dankserver/mariadb.md new file mode 100644 index 0000000..d6134db --- /dev/null +++ b/docs/Dankserver/mariadb.md @@ -0,0 +1,47 @@ +# MariaDB (RomM Backend) + +MariaDB 11 provides the database backend for RomM on Dankserver. RomM 5.2.0 requires MariaDB (or PostgreSQL) for its data store. + +**Host:** Dankserver — **Docs:** https://mariadb.com/kb/en/docker-mariadb-information/ + +## Facts + +| Item | Value | +|------|-------| +| Image | `docker.io/mariadb:11` | +| Port | 3306 (internal, within `appnet`) | +| Database name | `romm` | +| Data volume | `/opt/romm/mariadb` | + +## Docker Compose + +```yaml +mariadb: + image: docker.io/mariadb:11 + container_name: romm-mariadb + restart: unless-stopped + environment: + MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}" + MARIADB_DATABASE: romm + MARIADB_USER: "${ROMM_DB_USER}" + MARIADB_PASSWORD: "${ROMM_DB_PASSWD}" + volumes: + - /opt/romm/mariadb:/var/lib/mysql + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 3 +``` + +## Backup + +Back up the volume directory periodically: + +```bash +sudo rsync -a /opt/romm/mariadb /mnt/backup/romm-mariadb/ +``` + +## See Also + +- [[RomM]] — service that uses this database diff --git a/docs/Dankserver/prowlarr.md b/docs/Dankserver/prowlarr.md new file mode 100644 index 0000000..27841bb --- /dev/null +++ b/docs/Dankserver/prowlarr.md @@ -0,0 +1,55 @@ +# Prowlarr + +Prowlarr is the indexer management layer for the *arr stack. It aggregates indexers (torrent and Usenet) and exposes a unified API that Sonarr, Radarr, Lidarr, and Readarr consume. + +**Host:** Dankserver — **Hostname:** `prowlarr.dankserver.local` — **Docs:** https://wiki.servarr.com/prowlarr + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/prowlarr:latest` | +| Port | 9696 (host) → 9696 (container) | +| Min RAM | 256 MB | +| Auth | API key (Settings → General) | + +## Configuration + +1. Add indexers: Settings → Indexers → Add. +2. Test each indexer with the **Test** button. +3. Assign tags (e.g., `movies`, `tv`, `music`) to indexers for routing. +4. Add download client: Settings → Download Clients → Add qBittorrent. + +## Docker Compose + +```yaml +prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + container_name: prowlarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/prowlarr/config:/config + - /mnt/media/downloads:/downloads:ro + ports: + - "9696:9696" + networks: [appnet] +``` + +## Gotchas + +- Prowlarr database grows with indexer data. Set up periodic vacuum/backup. +- Indexer sync has a 15–60 minute delay. Search results may lag. +- Rotate API key: update it in every arr app. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation +- [[radarr]] +- [[sonarr]] +- [[lidarr]] +- [[readarr]] diff --git a/docs/Dankserver/qbittorrent.md b/docs/Dankserver/qbittorrent.md new file mode 100644 index 0000000..9cb60e2 --- /dev/null +++ b/docs/Dankserver/qbittorrent.md @@ -0,0 +1,52 @@ +# qBittorrent + +qBittorrent is the torrent download client for the *arr stack on Dankserver. It receives download requests from Sonarr, Radarr, Lidarr, and Readarr via category tagging. + +**Host:** Dankserver — **Hostname:** `qbittorrent.dankserver.local` — **Docs:** https://www.qbittorrent.org + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/qbittorrent:latest` | +| Port | 8080 (host) → 8080 (container) | +| Min RAM | 512 MB | +| Auth | Web UI username/password; LAN mode available | + +## Configuration + +1. Change the default Web UI password (Settings → Web UI). +2. Enable "No auth mode for LAN" for arr app connectivity (Settings → Web UI → uncheck "HTTP authentication required for clients"). +3. Create download categories: `movies`, `tv`, `music`, `books`. +4. Set max active downloads: Settings → Downloads (recommended: 5 global, 3 per category). + +## Docker Compose + +```yaml +qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: qbittorrent + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/qbittorrent/config:/config + - /mnt/media/downloads:/downloads + - /mnt/media/downloads/incomplete:/downloads/incomplete + ports: + - "8080:8080" + networks: [appnet] +``` + +## Gotchas + +- qBittorrent Web UI password changes on first run (check `config/qBittorrent.conf`). +- Ensure umask is set to `022` so downloaded files are readable by arr apps. +- Monitor bandwidth limits to avoid saturating the network. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation diff --git a/docs/Dankserver/radarr.md b/docs/Dankserver/radarr.md new file mode 100644 index 0000000..514ed3c --- /dev/null +++ b/docs/Dankserver/radarr.md @@ -0,0 +1,54 @@ +# Radarr + +Radarr manages movies in the *arr stack on Dankserver. It automatically searches, downloads, and organizes movies from indexers into the Jellyfin media library. + +**Host:** Dankserver — **Hostname:** `radarr.dankserver.local` — **Docs:** https://wiki.servarr.com/radarr + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/radarr:latest` (v4 stable) | +| Port | 7878 (host) → 7878 (container) | +| Min RAM | 512 MB | +| Metadata | TMDB / TheMovieDB API | + +## Docker Compose + +```yaml +radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/radarr/config:/config + - /mnt/media/movies:/movies + - /mnt/media/downloads:/downloads + ports: + - "7878:7878" + networks: [appnet] +``` + +## Configuration + +1. Add Prowlarr as the indexer source. +2. Add qBittorrent as the download client with the `movies` category. +3. Set quality profile and cutoff quality. +4. Set root folder to `/movies`. +5. Add movies and verify downloads. + +## Gotchas + +- Radarr v4 is the current stable. `:latest` points to v4, not v5. +- Movie renaming produces `Title (Year)` format. Jellyfin scanner handles this. +- File permissions: qBittorrent downloads as PUID; arr apps must read/move files. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation +- [[Jellyfin]] — media server that consumes Radarr downloads diff --git a/docs/Dankserver/readarr.md b/docs/Dankserver/readarr.md new file mode 100644 index 0000000..7be19fd --- /dev/null +++ b/docs/Dankserver/readarr.md @@ -0,0 +1,55 @@ +# Readarr + +Readarr manages ebooks and audiobooks in the *arr stack on Dankserver. It automatically searches, downloads, and organizes books into the Calibre library. + +**Host:** Dankserver — **Hostname:** `readarr.dankserver.local` — **Docs:** https://wiki.servarr.com/readarr + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/readarr:latest` (v0.2.x development) | +| Port | 8787 (host) → 8787 (container) | +| Min RAM | 256 MB | +| Metadata | Goodreads / StoryGraph | + +## Docker Compose + +```yaml +readarr: + image: lscr.io/linuxserver/readarr:latest + container_name: readarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/readarr/config:/config + - /mnt/media/books:/books + - /mnt/media/downloads:/downloads + ports: + - "8787:8787" + networks: [appnet] +``` + +## Configuration + +1. Add Prowlarr as the indexer source (torrent indexers with book content). +2. Add qBittorrent as the download client with the `books` category. +3. Set author profile (format preference: epub, mobi, etc.). +4. Set quality profile for audiobooks (320 kbps MP3, 128 kbps, lossless). +5. Set root folder to `/books`. +6. Add authors and verify downloads. + +## Gotchas + +- Readarr is in development (~v0.2.x). Some features may be incomplete. +- Calibre integration is folder-based, not API-based. Readarr drops files into `/books` which Calibre-Web serves. +- Not all indexers have all formats (epub, mobi, pdf). Goodreads/StoryGraph metadata helps match editions. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation +- [[Calibre-Web]] — ebook web frontend that serves Readarr downloads diff --git a/docs/Dankserver/redis.md b/docs/Dankserver/redis.md new file mode 100644 index 0000000..21b9cca --- /dev/null +++ b/docs/Dankserver/redis.md @@ -0,0 +1,40 @@ +# Redis (RomM Cache / Queue) + +Redis 7 provides the caching and task queue backend for RomM on Dankserver. RomM 5.2.0 requires Redis (or Valkey) for its task queue. + +**Host:** Dankserver — **Docs:** https://redis.io/docs/ + +## Facts + +| Item | Value | +|------|-------| +| Image | `docker.io/redis:7-alpine` | +| Port | 6379 (internal, within `appnet`) | +| Data volume | `/opt/romm/redis` | +| Auth | None (local-only, no password needed) | + +## Docker Compose + +```yaml +redis: + image: docker.io/redis:7-alpine + container_name: romm-redis + restart: unless-stopped + volumes: + - /opt/romm/redis:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 3 +``` + +## Backup + +```bash +sudo rsync -a /opt/romm/redis /mnt/backup/romm-redis/ +``` + +## See Also + +- [[RomM]] — service that uses this cache diff --git a/docs/Dankserver/sonarr.md b/docs/Dankserver/sonarr.md new file mode 100644 index 0000000..a71d98e --- /dev/null +++ b/docs/Dankserver/sonarr.md @@ -0,0 +1,55 @@ +# Sonarr + +Sonarr manages TV shows in the *arr stack on Dankserver. It automatically searches, downloads, and organizes episodes from indexers into the Jellyfin media library. + +**Host:** Dankserver — **Hostname:** `sonarr.dankserver.local` — **Docs:** https://wiki.servarr.com/sonarr + +## Facts + +| Item | Value | +|------|-------| +| Image | `lscr.io/linuxserver/sonarr:latest` (v4 stable) | +| Port | 8989 (host) → 8989 (container) | +| Min RAM | 512 MB | +| Metadata | TMDB / TVDB | + +## Docker Compose + +```yaml +sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - UMASK_SET=022 + volumes: + - /opt/sonarr/config:/config + - /mnt/media/tv:/tv + - /mnt/media/downloads:/downloads + ports: + - "8989:8989" + networks: [appnet] +``` + +## Configuration + +1. Add Prowlarr as the indexer source. +2. Add qBittorrent as the download client with the `tv` category. +3. Set quality profile, cutoff, and minimum/maximum episode sizes. +4. Set root folder to `/tv`. +5. Add series and verify downloads. + +## Gotchas + +- Sonarr v4 is the current stable. The v3 branch uses the `:v3` tag. +- Anime has different quality profiles and naming conventions than Standard series. +- Missing episodes: set "Unmonitor Missing Episodes" to auto-unmonitor old episodes. +- Timezone-sensitive scheduler: ensure all containers use the same TZ. + +## See Also + +- [[ARR-Stack]] — full *arr stack documentation +- [[Jellyfin]] — media server that consumes Sonarr downloads diff --git a/docs/index.md b/docs/index.md index bda0835..376a09d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,9 +26,20 @@ This repository tracks the container stacks for both hosts. Git is the single so ## Dankserver Services - [[RomM]] — retro game manager +- [[RomM-Scraping]] — metadata providers, cover art, naming conventions - [[Copyparty]] — file sharing and streaming +- [[Jellyfin]] — media server (movies, TV, music) - [[Calibre]] — e-book library engine - [[Calibre-Web]] — e-book web frontend +- [[ARR-Stack]] — automated media download overview +- [[sonarr]] — TV show management +- [[radarr]] — movie management +- [[lidarr]] — music management +- [[readarr]] — ebook/audiobook management +- [[prowlarr]] — indexer management +- [[qbittorrent]] — torrent download client +- [[mariadb]] — RomM database backend +- [[redis]] — RomM cache/queue backend ## Dankclaw Services @@ -59,6 +70,8 @@ This repository tracks the container stacks for both hosts. Git is the single so - [[ComfyUI ROCm and Vulkan]] — live-verified GPU path for ComfyUI on Strix Halo - [[Lemonade and sd.cpp]] — the ggml-family image-generation alternative - [[Backblaze Integration]] — off-site backup plan (future) +- [[Jellyfin]] — media server research brief +- [[ARR-Stack]] — automated download stack research brief ## See Also