Note: This repository is a portfolio project demonstrating the HELIOS architecture and user experience. It is not a turnkey deployment and is not intended to be cloned or run as-is.
HELIOS is a self-hosted media management and server administration system running as Docker containers inside a Proxmox VE virtual machine. It automates the full media lifecycle β request, indexing, download, post-processing, and streaming β while providing centralized dashboards for container and server operations.
This repository showcases the architecture and engineering around that system: modular Docker Compose orchestration, a shared Bash operational library, non-destructive image-update tooling with health checks, NVIDIA GPU passthrough for Plex transcoding, and file-based Docker Secrets management.
| Category | Service | Purpose | |
|---|---|---|---|
| π¬ Media Management | Wizarr | User Invitation & Onboarding | |
| Radarr | Movie Collection & Downloads | ||
| Sonarr | TV Series Collection & Downloads | ||
| Bazarr | Subtitle Management | ||
| Seerr | Media Request & Discovery | ||
| Prowlarr | Indexer Management | ||
| Recyclarr | TRaSH Guide Sync | ||
| SABnzbd | Usenet Download Client | ||
| Plex | Media Server & Streaming | ||
| Plex Auto Languages | Automated Language Management | ||
| π Server Management | Portainer | Container Management | |
| Tautulli | Media Server Analytics | ||
| Homarr | Dashboard & Service Management | ||
| FlareSolverr | Proxy & Anti-Bot Protection | ||
| π§ Infrastructure | Proxmox VE | Virtualization Platform | |
| Docker | Containerization Platform | ||
The media stack forms an invite-to-streaming pipeline:
- Wizarr β admins generate self-serve invite links with optional expiry, one-time use, and library-tier access. Invitees click the link, sign in via Plex OAuth, and walk through a multi-step onboarding wizard that hands them off to Seerr and surfaces server-status channels. Wizarr auto-adds the user as a Plex friend in the background β no manual invite handling.
- Seerr β users browse and request content. Requests are routed to Radarr (movies) or Sonarr (TV). New Plex sign-ins are auto-imported with default permissions.
- Prowlarr β centralized indexer manager. Feeds indexers and API keys into Sonarr and Radarr so each *arr doesn't maintain its own.
- Radarr / Sonarr β monitor requests, search Prowlarr-fed indexers, hand releases to SABnzbd, then import and rename finished files into the media libraries.
- SABnzbd β Usenet client. Downloads into
/mnt/usenet/incomplete/, moves to/mnt/usenet/complete/on success for *arr post-processing. - Recyclarr β runs weekly (
@weeklycron). Syncs TRaSH Guide custom formats and quality profiles into Sonarr/Radarr so their release scoring stays current without manual tuning. - Bazarr β watches Sonarr/Radarr for imports, pulls subtitles from configured providers, writes them alongside the media files.
- Plex β serves the finished libraries at
/mnt/media/moviesand/mnt/media/tv. Transcodes via NVIDIA GPU when clients can't direct-play. - Plex Auto Languages β watches Plex sessions and auto-sets audio and subtitle preferences per user based on their configured language.
Operational services run alongside the pipeline:
- Homarr β landing dashboard with service status, quick links, and live Docker integration
- Portainer (+ Agent) β container, image, network, and volume management over an isolated agent network
- Tautulli β Plex watch history, stats, and notifications
- FlareSolverr β Cloudflare bypass proxy used by Prowlarr for protected indexers
- Modular Compose: the root
docker-compose.ymluses Compose v2includeto pull indeployments/console/docker-compose.ymlanddeployments/media/docker-compose.yml. Each sub-stack usesx-commonYAML anchors for DRY service configuration (restart policy, PUID/PGID, TZ, UMASK). - 3-network topology:
helios_proxyβ external access (Homarr, FlareSolverr, Tautulli)helios_console_agent_networkβ isolated Portainer β Agent channelhelios_defaultβ main network for all media services
- File-based Docker Secrets stored at
/etc/HELIOS/secrets/(symlinked into the repo). Keeps credentials out of env files and out of git. - Centralized environment:
env.shis a symlink to/etc/HELIOS/env.sh, auto-loaded by direnv oncd. The.envconsumed by Docker Compose is regenerated bysystem-verify.sh. - NVIDIA GPU passthrough for Plex, paired with an inline 16 GB
plex_transcodetmpfs volume β faster transcoding and auto-cleanup on container stop. - Docker socket integration for Homarr with proper group permissions so the dashboard can surface live container state without running privileged.
The engineering surface lives in scripts/ and the Compose files:
scripts/_common.shβ shared Bash library sourced by every script. Providesset -euo pipefail, path and root detection, env sourcing, color logging, ERR/EXIT traps, and opt-out flags:HELIOS_NO_ERREXIT=1for scripts that need to continue past failures (e.g.test-api-connectivity.sh), andHELIOS_START_MSGfor custom banners.scripts/docker-rebuild.shβ non-destructive image update. Never runscompose down; onlypull+up --remove-orphans, so containers with unchanged images are left running. Features:--dry-run,--skip-prune,--skip-health-check,--project-dir; structured exit codes (0healthy /1partial /2complete failure); NVIDIA CDI spec regeneration after driver updates; Plex version drift detection against the PlexPass/public channel;jq-based post-update health check with severity assessment; up to 3 retry attempts for transient D-state failures.scripts/system-verify.shβ validates Docker/Compose availability, env vars, secrets file presence and600permissions, and external networks/volumes. Auto-generates.envfromenv.shfor Compose consumption.scripts/test-api-connectivity.shβ end-to-end API probes across all services using per-service tokens (Plex token, Homarr API key viaApiKeyheader, Portainer token viaX-API-Keyover HTTPS 9443).scripts/compose-up.sh/compose-down.sh/compose-refresh.shβ lifecycle scripts.compose-refreshdelegates to the other two as subprocesses so each phase produces its own log file.scripts/media-clean.shβ purges Usenetcomplete/andincomplete/directories, cycling SABnzbd around the cleanup.
All scripts log dual-output to console and logs/<script>.log.
/mnt # Base storage location (LOAS - Location Of All Storage)
βββ media/ # Media library root
β βββ movies/ # Movie library (mounted to Radarr, Bazarr, Plex)
β βββ tv/ # TV library (mounted to Sonarr, Bazarr, Plex)
βββ usenet/ # Download directory
βββ complete/ # Completed downloads (processed by *arr services)
βββ incomplete/ # Active downloads (SABnzbd working directory)
/etc/HELIOS/ # Centralized configuration root
βββ config/ # Service configuration directories
β βββ wizarr/ # Wizarr configuration (SQLite DB + onboarding state)
β βββ seerr/ # Seerr configuration
β βββ radarr/ # Radarr configuration
β βββ sonarr/ # Sonarr configuration
β βββ bazarr/ # Bazarr configuration
β βββ prowlarr/ # Prowlarr configuration
β βββ recyclarr/ # Recyclarr configuration
β βββ sabnzbd/ # SABnzbd configuration
β βββ plex/ # Plex Media Server configuration
β βββ plexautolanguages/ # Plex Auto Languages configuration
β βββ tautulli/ # Tautulli configuration
β βββ flaresolverr/ # FlareSolverr configuration
β βββ homarr/ # Homarr configuration
βββ secrets/ # Docker Secrets (symlinked from project root)
helios_portainer_dataβ Portainer settings and management datahelios_homarr_dataβ Homarr dashboard data and application stateplex_transcodeβ inline 16 GB tmpfs volume for Plex transcoding (RAM-backed, auto-cleanup on container stop)plex_downloadsβ disk-backed volume for Plex download staging (/downloadsinside the container)
Follows LinuxServer.io conventions: PUID=1000, PGID=984, UMASK=002. Media libraries, config directories, and download directories are all owned 1000:984 with 755; UMASK=002 makes new files group-writable for multi-user access.
Full version history in CHANGELOG.md.