Overview
The media stack provides automated content acquisition, organization, and streaming. Services are split between Unraid (Plex for hardware transcoding) and docker-prod-01 (ARR automation stack).Plex
Media server with hardware transcoding
ARR Stack
Automated content management
Torrents
VPN-protected downloading
Requests
User request interface
Plex Media Server
Location: nas-prod-01 (Unraid native Docker) IP Address: Accessible via Traefik at 192.168.30.11 Why Unraid?- Direct access to i5-13400 Intel UHD 730 iGPU for QuickSync hardware transcoding
- No NFS hop - Plex reads media directly from local filesystem
- No iGPU passthrough complexity
- QuickSync on 12th/13th gen Intel handles 2+ simultaneous 1080p transcodes
Hardware Transcoding
iGPU: Intel UHD 730 (i5-13400) Capability:- 2+ simultaneous 1080p transcodes
- Hardware-accelerated H.264 and HEVC
- Tone mapping for HDR content
- Low power consumption vs dedicated GPU
- Settings → Transcoder → Use hardware acceleration when available: Enabled
- Transcode temp directory: Local Unraid directory (not NFS)
Library Structure
Media paths (NFS from Unraid):- Movies (1080p) - Shared with all users
- Movies (4K) - Local viewing only (Apple TV 4K via Infuse)
- TV Shows
- Anime
- Audiobooks
External Access
Method: Direct port forwarding (NOT Cloudflare Tunnel) Configuration:- UDM-SE port forward:
32400 → nas-prod-01 - Plex handles TLS natively
- Remote access enabled in Plex settings
Backup
Plex database backup script:- Runs nightly via cron on nas-prod-01
- Stops Plex service
- Backs up
/opt/appdata/plex/to NAS/backups/plex/db - Restarts Plex service
- Uses EXIT trap to ensure service restart even on failure
- Internal:
https://plex.giohosted.com - External:
https://app.plex.tv - Configuration: Unraid Docker settings
ARR Stack
Location: docker-prod-01 (192.168.30.11) Stack:/opt/stacks/arr/compose.yaml
Services
Sonarr (TV)
Regular TV show automation
Sonarr (Anime)
Anime-specific automation with custom profiles
Radarr (1080p)
1080p movie automation for shared users
Radarr (4K)
4K WebDL automation for local viewing
Sonarr (TV)
Purpose: Automate TV show downloads and organization Access:https://sonarr.giohosted.com
Configuration:
- Root folder:
/data/media/tv/ - Download client: qBittorrent
- Indexer management: Prowlarr
- Quality profiles: TRaSH Guides recommendations
- Sonarr monitors RSS feeds via Prowlarr
- Selects release matching quality profile
- Sends to qBittorrent (via Gluetun VPN)
- qBit downloads to
/data/downloads/tv/ - Sonarr detects completion
- Hardlinks file to
/data/media/tv/(atomic move, no copy) - Plex detects new file and updates library
- Original file remains seeding in
/data/downloads/tv/
Hardlinks require downloads and media to be on the same filesystem. Both are on Unraid parity array with no cache involvement.
Sonarr (Anime)
Purpose: Separate instance for anime with specialized profiles Access:https://sonarr-anime.giohosted.com
Why separate instance?
- Anime release groups use different naming conventions
- Quality profiles focus on fansub groups vs WEB-DL
- Different preferred words and must-not-contain filters
- Separate library organization
- Root folder:
/data/media/anime/ - Custom quality profiles for anime releases
- Preferred release groups configured per TRaSH Guides anime section
Radarr (1080p)
Purpose: Automate 1080p movie downloads for shared users Access:https://radarr.giohosted.com
Configuration:
- Root folder:
/data/media/movies/1080p/ - Quality profile: 1080p WebDL/Bluray
- Optimized for streaming without transcoding
- Shared with all Plex users
Radarr (4K)
Purpose: 4K WebDL movies for local high-quality viewing Access:https://radarr-4k.giohosted.com
Configuration:
- Root folder:
/data/media/movies/4k/ - Quality profile: 4K WebDL (not remux - file size balance)
- Target: Apple TV 4K direct play via Infuse
- Not transcoded for remote users
- Different quality requirements (4K WebDL vs 1080p)
- Separate library in Plex
- Prevents accidental 4K downloads for shared library
- Isolated indexer priorities for 4K releases
Prowlarr
Purpose: Centralized indexer management for all ARR instances Access:https://prowlarr.giohosted.com
Connected instances:
- Sonarr (TV)
- Sonarr (Anime)
- Radarr (1080p)
- Radarr (4K)
- Indexers automatically synced to all ARR apps
- Single point of indexer management
- Add indexer once, available everywhere
- Flaresolverr integration for Cloudflare-protected indexers
Bazarr
Purpose: Automated subtitle downloads Access:https://bazarr.giohosted.com
Configuration:
- Syncs with Sonarr and Radarr libraries
- Preferred languages configured
- Subtitle providers: OpenSubtitles, Subscene, etc.
- Automatically downloads missing subtitles
- Upgrades to better quality subtitles when available
Supporting Services
Profilarr:- Manages quality profiles across Sonarr/Radarr instances
- Syncs TRaSH Guides recommendations
- Access:
https://profilarr.giohosted.com
- Media lifecycle visibility
- Shows watched/unwatched statistics
- Identifies content for potential removal
- Note: Configured for visibility only, no automatic deletion
- Access:
https://maintainerr.giohosted.com
- Plex analytics and monitoring
- Play statistics and user activity
- Newsletter generation
- Access:
https://tautulli.giohosted.com
- Cloudflare bypass for Prowlarr
- Proxies requests to Cloudflare-protected indexers
- Runs as supporting service (no direct access needed)
Torrent Stack
Location: docker-prod-01 Stack:/opt/stacks/torrent/compose.yaml
Architecture
Gluetun
Purpose: VPN killswitch for qBittorrent Configuration:- VPN provider: ProtonVPN
- Server: Chicago (port forwarding support)
- Protocol: WireGuard
- Killswitch: Enabled (blocks all traffic if VPN drops)
qBittorrent
Purpose: Torrent download client Access:https://qbittorrent.giohosted.com
Configuration:
- Download path:
/data/downloads/ - Categories:
tv→/data/downloads/tv/movies→/data/downloads/movies/anime→/data/downloads/anime/books-ebooks→/data/downloads/books/ebooks/downloads/books-audiobooks→/data/downloads/books/audiobooks/downloads/
- Automatic via Gluetun integration with ProtonVPN
- Verified as “Fully Connectable” on private trackers
qBitrr
Purpose: Torrent lifecycle management for all ARR instances Replaces: Customqbit-automation sidecar from v2
Access: https://qbitrr.giohosted.com
Features:
- Single installation manages all 4 ARR instances
- Seeding time enforcement (14 days minimum for MAM ebooks/audiobooks)
- Failed torrent detection and redownload triggering
- Stalled torrent monitoring
- Web UI for troubleshooting
- Sonarr (TV)
- Sonarr (Anime)
- Radarr (1080p)
- Radarr (4K)
Seerr (Request Interface)
Purpose: User-facing request portal for movies and TV shows Access:- Internal:
https://request.giohosted.com - External:
https://request.giohosted.com(via Cloudflare Tunnel)
- Connects to Sonarr (TV), Sonarr (Anime), Radarr (1080p), Radarr (4K)
- Users request content via web interface
- Requests automatically sent to appropriate ARR instance
- Status tracking and notifications
- Protected by Cloudflare Access
- Users authenticated via Authentik OIDC
Storage and Hardlinks
Critical Design Requirement
Why hardlinks matter:- qBittorrent downloads file to
/data/downloads/tv/show.mkv - Sonarr creates hardlink at
/data/media/tv/Show/show.mkv - Same file, two paths - zero additional disk usage
- File continues seeding from original download location
- Deleting either path does not affect the other until both are removed
- Downloading to cache pool while media is on array
- Copying instead of moving/hardlinking
- Crossing filesystem boundaries
Directory Structure
On docker-prod-01 (/data = NFS mount to nas-prod-01 /mnt/user):
Migration Notes
4K Movie Migration (Phase 4)
Existing 4K movies previously managed by single Radarr instance need migration to Radarr (4K):- Use Radarr (4K) Movie Editor to bulk-select existing 4K titles
- Assign correct root folder:
/data/media/movies/4k/ - Trigger library rescan in Radarr (4K)
- Existing files re-pathed and monitoring assigned
- No re-download required - files already in correct location
Troubleshooting ARR Stack
Troubleshooting ARR Stack
Hardlinks not working:
- Verify both downloads and media are on same share:
df -h /data/downloads /data/media - Check Unraid share settings: Downloads and media shares must have “Use cache: No”
- Verify ARR using “Hardlink” or “Move” not “Copy”
- Test manually:
ln /data/downloads/test.txt /data/media/test.txt
- Check qBittorrent category matches ARR instance download folder
- Verify file permissions: Should be
2000:2000 - Check ARR logs for import errors
- Verify NFS mount is healthy:
mount | grep /data
- Check Gluetun logs:
docker logs gluetun - Verify public IP:
docker exec qbittorrent curl ifconfig.me - Should show ProtonVPN IP, not residential
- Check port forwarding status in qBittorrent settings
- Verify ARR API keys in qBitrr config
- Check qBitrr web UI for connection status
- Ensure categories in qBittorrent match qBitrr config
- Review qBitrr logs for errors