docs: fact-check sweep, Jellyfin, *arr stack, and ROM scraping guides

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.
This commit is contained in:
Frank
2026-08-20 23:40:07 -07:00
parent 34918bf309
commit e8fd009419
20 changed files with 1901 additions and 58 deletions
+18 -1
View File
@@ -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
+46 -3
View File
@@ -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
# }
+199 -3
View File
@@ -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
+369
View File
@@ -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<br/>Torrents, Usenet] --> P[Prowlarr<br/>Indexer Manager]
P --> S[Sonarr<br/>TV]
P --> R[Radarr<br/>Movies]
P --> L[Lidarr<br/>Music]
P --> Rd[Readarr<br/>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
+65 -16
View File
@@ -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
+49 -7
View File
@@ -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
+76 -13
View File
@@ -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
+23 -1
View File
@@ -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
+173
View File
@@ -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
+296
View File
@@ -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-<random hash>`, 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 |
|-----------------|-------------|
| `<cover>` | `covers/` |
| `<backcover>` | `backcovers/` |
| `<box3d>` | `3dboxes/` |
| `<marquee>` | `marquees/` |
| `<screenshot>` | `screenshots/` |
| `<fanart>` | `fanart/` |
| `<manual>` | `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=<strong password>
ROMM_AUTH_SECRET_KEY=$(openssl rand -hex 32)
# Metadata Providers
IGDB_CLIENT_ID=<your-client-id>
IGDB_CLIENT_SECRET=<your-client-secret>
SCREENSCRAPER_USER=<screenscraper-username>
SCREENSCRAPER_PASSWORD=<screenscraper-password>
MOBYGAMES_API_KEY=<mobygames-key>
RETROACHIEVEMENTS_API_KEY=<retroachievements-api-key>
STEAMGRIDDB_API_KEY=<steamgriddb-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
+163 -14
View File
@@ -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
+53
View File
@@ -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
+47
View File
@@ -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
+55
View File
@@ -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]]
+52
View File
@@ -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
+54
View File
@@ -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
+55
View File
@@ -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
+40
View File
@@ -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
+55
View File
@@ -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
+13
View File
@@ -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