Your all-in-one Helm chart for your media needs!
A Helm chart for deploying a complete media server stack on Kubernetes, including:
- Plex Media Server - A complete and fully functional mediaserver that allows you to render in a webUI your movies, TV Series, podcasts, video streams.
- Jellyfin - An alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps
- Sonarr - A TV series and show tracker, that allows the integration with download managers for searching and retrieving TV Series, organizing them, schedule notifications when an episode comes up and much more.
- Radarr - The same as Sonarr, but for movies!
- Jackett - An API interface that keeps easy your life interacting with trackers for torrents.
- Prowlarr - An indexer manager/proxy built on the popular *arr .net/reactjs base stack to integrate with your various PVR apps. Prowlarr supports management of both Torrent Trackers and Usenet Indexers.
- Transmission - A fast, easy and reliable torrent client.
- Sabnzbd - A free and easy binary newsreader.
- Seerr - Media request and discovery manager for Jellyfin, Plex, and Emby.
This repository contains:
- Umbrella Chart (
k8s-mediaserver) - Deploys all services together with shared configuration - Individual Service Charts - Each service (sonarr, radarr, plex, etc.) can be installed independently
All container images used by the chart are from linuxserver.io except Seerr which uses the official image from seerr-team.
Each of the components can be enabled or disabled if you already have something in place in your lab!
This Helm chart provides a simple and minimalistic way to deploy a complete media server stack on Kubernetes, with customizations that are strictly related to usability and access, rather than complex customizations.
Each container has its init container in order to initialize configurations on the PV before starting the actual pod and avoid restarting the pods.
The chart is structured as an umbrella chart with individual service charts as dependencies, allowing you to:
- Install all services together with shared configuration
- Install individual services independently
- Mix and match services as needed
- A Kubernetes cluster (1.19+)
- Helm 3.x
- A namespace where you want to deploy the chart
- Being able to provision an RWX PV where to store configurations, downloads, and all related stuff (suggested > 200GB). Persistent Volume or StorageClasses for dynamically provisioned volumes are REQUIRED (See below for NFS)
- Add the Helm repository (if using a chart repository):
helm repo add k8s-mediaserver-charts https://95gabor.github.io/k8s-mediaserver-charts
helm repo update- Install the umbrella chart with default values:
# Using local chart directory
helm dependency update ./charts/k8s-mediaserver
helm upgrade --install k8s-mediaserver ./charts/k8s-mediaserver \
-n k8s-mediaserver --create-namespace
# Or from chart repository
helm upgrade --install k8s-mediaserver k8s-mediaserver-charts/k8s-mediaserver \
-n k8s-mediaserver --create-namespace- (Optional) Use custom values:
# Copy the default values file
cp ./charts/k8s-mediaserver/values.yaml my-values.yaml
# Edit my-values.yaml with your custom settings
# Install with custom values
helm dependency update ./charts/k8s-mediaserver
helm upgrade --install k8s-mediaserver ./charts/k8s-mediaserver \
-n k8s-mediaserver --create-namespace \
-f my-values.yamlYou can also install individual service charts independently:
# Example: Install only Sonarr
helm upgrade --install sonarr ./charts/sonarr \
-n sonarr --create-namespace \
-f ./charts/sonarr/values.yaml
# Example: Install only Plex
helm upgrade --install plex ./charts/plex \
-n plex --create-namespace \
-f ./charts/plex/values.yamlSee the charts README for a complete list of available charts.
# Update dependencies first
helm dependency update ./charts/k8s-mediaserver
# Then upgrade
helm upgrade k8s-mediaserver ./charts/k8s-mediaserver \
-n k8s-mediaserver \
-f my-values.yaml# Uninstall umbrella chart (removes all services)
helm uninstall k8s-mediaserver -n k8s-mediaserver
# Or uninstall individual services
helm uninstall sonarr -n sonarrWith default settings, your applications will run at these paths:
| Service | Link |
|---|---|
| Sonarr | http://k8s-mediaserver.k8s.test/sonarr |
| Radarr | http://k8s-mediaserver.k8s.test/radarr |
| Transmission | http://k8s-mediaserver.k8s.test/transmission |
| Jackett | http://k8s-mediaserver.k8s.test/jackett |
| Prowlarr | http://k8s-mediaserver.k8s.test/prowlarr |
| Sabnzbd | http://k8s-mediaserver.k8s.test/sabnzbd |
| Seerr | http://k8s-mediaserver.k8s.test/seerr |
| Jellyfin | http://k8s-jelly.k8s.test/ |
| PLEX | http://k8s-plex.k8s.test/ |
The chart is quite simple to configure, with a low number of parameters to avoid confusion, while still allowing customization to fit the resources inside your cluster.
Note: The umbrella chart (
k8s-mediaserver) only contains overrides and service-specific configurations. For complete documentation of all available values for each service chart, see the individual chart directories:
See the values.yaml file for umbrella chart configuration options, or check the Helm chart README for detailed documentation.
Key configuration options:
general.ingress_host- The hostname to use in ingress definition (default:k8s-mediaserver.k8s.test)general.plex_ingress_host- The hostname for PLEX (default:k8s-plex.k8s.test)general.jellyfin_ingress_host- The hostname for JellyFin (default:k8s-jelly.k8s.test)general.pgid- The GID for the process (default:1000)general.puid- The UID for the process (default:1000)general.storage.pvcName- Name of the persistentVolumeClaim (default:mediaserver-pvc)general.storage.size- Size of the persistentVolume (default:5Gi)general.storage.subPaths.*- Subpaths for different media types
Each service can be enabled/disabled and configured individually:
{service}.enabled- Enable or disable the service{service}.container.image- Container image{service}.container.tag- Container image tag (pinned versions recommended){service}.service.type- Service type (ClusterIP/NodePort/LoadBalancer){service}.ingress.enabled- Enable ingress{service}.resources- Resource limits and requests
This repository contains the following Helm charts:
- k8s-mediaserver - Umbrella chart (deploys all services)
- sonarr - TV series tracker
- radarr - Movie tracker
- plex - Media server
- jellyfin - Alternative media server
- jackett - Torrent tracker API
- prowlarr - Indexer manager
- transmission - Torrent client
- sabnzbd - Usenet client
- seerr - Media request manager
Each chart has its own README with detailed documentation. See charts/README.md for more information.
This assumes that you have a pre-configured NFS server set up on your network that is accessible from all nodes. If it is not accessible by all nodes, pods will not enter ready state when scheduled on nodes that do not have NFS access.
To add an NFS volume to each resource, edit your values.yaml to match the snippet below. You should change the server: and path: values to match your NFS.
general:
storage:
customVolume: true
volumes:
nfs:
server: { SERVER-IP }
path: /mount/path/on/nfs/server/If you need an extra load balancer on any service, you can either enable it like this:
plex:
service:
extraLbService:
enabled: trueor like this, if you need to add annotations to it (for use with cloud providers to configure the load balancer for example):
plex:
service:
extraLbService:
enabled: true
annotations:
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "Key=Value"-
Install pre-commit:
pip install pre-commit
-
Install git hooks:
pre-commit install pre-commit install --hook-type commit-msg
This will automatically run checks before each commit, including:
- Conventional commit message validation
- YAML syntax checking
- Helm chart linting
- Documentation generation
- File formatting checks
-
Run pre-commit on all files (optional):
pre-commit run --all-files
pre-commit run --all-fileshelm template test-release ./charts/k8s-mediaserver -f ./charts/k8s-mediaserver/values.yamlhelm package ./charts/k8s-mediaserverhelm-docs --chart-search-root=chartsThis project uses Conventional Commits. Commit messages should follow this format:
<type>(<scope>): <subject>
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(seerr): add init container for permission setupfix(sonarr): correct ingress path configurationdocs(readme): update installation instructions
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines on:
- Development setup
- Code style guidelines
- Pull request process
- Chart development guidelines
Special thanks to kubealex (Alessandro Rossi) for creating the original k8s-mediaserver project. This repository is a fork with enhancements including:
- Split into individual service charts with umbrella chart support
- Added Seerr media request manager
- Improved chart structure and maintainability
- Updated documentation and examples
This project is intended as an exercise, and absolutely for fun. This is not intended to promote piracy.
Also feel free to contribute and extend it!