{"id":13550001,"url":"https://github.com/pabloromeo/clusterplex","last_synced_at":"2025-04-02T23:31:33.938Z","repository":{"id":37001379,"uuid":"193298772","full_name":"pabloromeo/clusterplex","owner":"pabloromeo","description":"ClusterPlex is an extended version of Plex, which supports distributed Workers across a cluster to handle transcoding requests.","archived":false,"fork":false,"pushed_at":"2024-08-17T15:43:31.000Z","size":2310,"stargazers_count":467,"open_issues_count":10,"forks_count":35,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-11-03T19:37:30.457Z","etag":null,"topics":["cluster","distributed-transcoding","docker","docker-swarm","kubernetes","plex","plex-media-server","swarm","transcoding"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pabloromeo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-23T02:39:46.000Z","updated_at":"2024-11-03T10:48:57.000Z","dependencies_parsed_at":"2024-01-13T16:25:20.647Z","dependency_job_id":"2bc2739c-ce30-4213-a4a5-0c081235be89","html_url":"https://github.com/pabloromeo/clusterplex","commit_stats":null,"previous_names":[],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pabloromeo%2Fclusterplex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pabloromeo%2Fclusterplex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pabloromeo%2Fclusterplex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pabloromeo%2Fclusterplex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pabloromeo","download_url":"https://codeload.github.com/pabloromeo/clusterplex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246911022,"owners_count":20853652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cluster","distributed-transcoding","docker","docker-swarm","kubernetes","plex","plex-media-server","swarm","transcoding"],"created_at":"2024-08-01T12:01:27.930Z","updated_at":"2025-04-02T23:31:32.500Z","avatar_url":"https://github.com/pabloromeo.png","language":"JavaScript","funding_links":[],"categories":["HarmonyOS","JavaScript"],"sub_categories":["Windows Manager"],"readme":"# ClusterPlex\n[![GitHub license](https://img.shields.io/github/license/pabloromeo/clusterplex.svg)](https://github.com/pabloromeo/clusterplex/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/pabloromeo/clusterplex.svg)](https://GitHub.com/pabloromeo/clusterplex/releases/)\n[![ci](https://github.com/pabloromeo/clusterplex/actions/workflows/main.yml/badge.svg)](https://github.com/pabloromeo/clusterplex/actions)\n\n## What is it?\n\nClusterPlex is basically an extended version of [Plex](https://plex.tv), which supports distributed Workers across a cluster to handle transcoding requests.\nIt has been tested on Kubernetes and Docker Swarm.\n\n![Kubernetes](docs/images/kubernetes-logo-small.png)\n\n![Docker Swarm](docs/images/docker-swarm-logo-small.png)\n\n\n## Components\n\nIt's made up of 3 parts:\n\n* ### Plex Media Server\n  There are two alternatives here:\n  1. **RECOMMENDED:** Running the Official LinuxServer Plex image (ghcr.io/linuxserver/plex:latest) and applying the ClusterPlex dockermod (ghcr.io/pabloromeo/clusterplex_dockermod:latest)\n  2. Running the ClusterPlex PMS docker image (ghcr.io/pabloromeo/clusterplex_pms:latest)\n* ### Transcoding Orchestrator\n  Running a container using ghcr.io/pabloromeo/clusterplex_orchestrator:latest\n* ### Transcoding Workers\n  Just as with PMS, two alternatives:\n  1. **RECOMMENDED:** Official image (ghcr.io/linuxserver/plex:latest) with the Worker dockermod (ghcr.io/pabloromeo/clusterplex_worker_dockermod:latest)\n  2. Custom Docker image: ghcr.io/pabloromeo/clusterplex_worker:latest\n\n## How does it work?\n\n![Overview](docs/images/overview.png)\n\n* In the customized PMS server, Plex’s own transcoder is renamed and a shim is put in its place which calls a small Node.js app that communicates with the Orchestrator container over websockets.\nAlso, a Local Relay is installed (an NGINX forward-proxy) which forwards calls coming from Workers to PMS as if they were made locally.\n\n* The Orchestrator (Node.js application which receives all transcoding requests from PMS) forwards it to one of the active Workers available over websockets.\n\n* Workers receive requests from the Orchestrator and kick off the transcoding and report progress back to the Local Relay running on PMS. Workers can come online or go offline and the Orchestrator manages their registrations and availability. These Workers can run as replicated services managed by the cluster.\n\n## Requirements\n\nYou will need to have a mechanism for sharing content between PMS and your Workers that supports ReadWriteMany (RWX).\n\nThis can be NFS, SMB, Ceph, GlusterFS or Longhorn, to name a few.\n\nThe content that needs to be shared are the *Media Libraries*, and the *transcoding* location, and paths MUST be the same on all workers and the main PMS.\n\n## Shared Storage\n\n### Media Libraries\n\nIn order for Workers to function properly, all Media content should be shared using identical paths between PMS and the Workers.\nThis would be using network shared storage supporting ReadWriteMany (RWX), such as NFS, SMB, Ceph, GlusterFS, Longhorn, etc.\n\n### Transcoding location\n\nThe same applies to the **/transcode** directory, in both PMS and the Workers. You CAN use a different directory name other than `/transcode`, however, it MUST match between PMS and all Workers, as well as be configured within Plex as the transcoding path:\n\n![transcode-path](docs/images/transcode-path.png)\n\n## Non-shared Persistent Storage\n\n### Plex Application Data\n**IMPORTANT:** PMS's Application Data mount (/config) does NOT need to be shared with the Workers, so you can use your preferred method for persistent storage. Just beware that Plex doesn't play very well with network storage for this, especially regarding symlinks and file locks (used by their sqlite db).\n\n**The recommendation is to use Ceph, Longhorn or GlusterFS.**\n\n\n### Codecs\n\nWorkers require a path to store downloaded codecs for the particular architecture of the Worker.\nCodecs are downloaded when the worker container starts up.\n\nThe path within the container is **/codecs**, which you can mount to a volume in order to have them persisted across container recreations. Subdirectories for each plex version and architecture are created within it.\n\n## Network settings in PMS ##\nLatest versions of ClusterPlex don't require any special network configuration, due to the new **Local Relay** functionality which forwards calls from Workers to Plex, which is enabled by default.\n\nHowever, if you have disabled Local Relay by setting `LOCAL_RELAY_ENABLED` to `\"0\"`, then in Plex's `Network` Configuration, you must add the IPs or the range that will be used by Workers to the `\"List of IP addresses and networks that are allowed without auth\"`.\n\nFor example:\n![network-ips](docs/images/network-ips.png)\n\n## Installation\n\nSee the [docs](docs/) section for details on each component's configuration parameters and example configurations both on Kubernetes and Docker Swarm.\n\n* [Configuration Parameters](docs/)\n* [On Kubernetes](docs/kubernetes/)\n* [On Docker Swarm](docs/docker-swarm/)\n* [Grafana Dashboard and Metrics](docs/grafana-dashboard/)\n* [On Kubernetes via Helm](https://pabloromeo.github.io/clusterplex)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpabloromeo%2Fclusterplex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpabloromeo%2Fclusterplex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpabloromeo%2Fclusterplex/lists"}