ressu / kube-plex

Scalable Plex Media Server on Kubernetes -- dispatch transcode jobs as pods on your cluster!
Apache License 2.0
102 stars 24 forks source link

thinking about a custom plex image, or initContainer side pod #35

Closed lknite closed 7 months ago

lknite commented 2 years ago

What do you think of the idea of having a slightly custom plex image based off of whatever the latest plex image is?

Here's what I'm thinking, There are a few settings I'd like to be able to set via a values.yaml file such as:

The default plex media server image doesn't let you customize a lot. Maybe there could be some sort of project which people could contribute to, which somehow creates a way to add a customization setting? Like, someone figures out where the transcoder setting is, so they create a script which lets that value be set, and we have a plex image which pulls the specified or latest pms image, copies in the customization folder, then passes along settings from the values.yaml somehow into this "customizable plex image".

I think I might be motivated enough to create this. Though, for me it'd have a learning curve to setup the pipeline. I've been getting up to speed with kubernetes for a year and only just now getting around to creating pipelines. However, given I have experience scripting, I'd also be ok with just adding features if such a project existed.

lknite commented 2 years ago

Or maybe, we could have a pod with an 'initContainer' side pod that uses environment variables configured via a values.yaml file that does all the additional configuration before the main one kicks on. I've see that implementation in the jenkinscsi helm chart.

The jenkinscsi helm chart takes a list of plugins that are defined in the values.yaml and installs those with the init container. It has a script in a configmap which is run in the initContainer, so you can change the script which runs in the initContainer to whatever you want. The script by default runs a utility which installs the plugins. We could use the same approach to run a script of some sort which executes "plugins" we design which simply set configurations.

The more I think about it, this is starting to sound like the better approach. I could generate a pull request with this approach and then work on the script which can call configuration scripts along with the above configurations I want, but we could be open to other people creating scripts to customize the setting they like. What do you think? -- If it was a new custom plex image though, which wraps around the real image ... then it could more easily be a separate project, and people not using kubernetes could still use it.

lknite commented 2 years ago

I'll start working on a script to call other scripts to customize settings based on environment variables. Such a script could run from within a customized plex container, or via an initContainer.

https://github.com/lknite/plex-config

lknite commented 2 years ago

or maybe, simply as a postStart

ressu commented 2 years ago

I have a number of things I don't like about the container image for plex. So building a custom image is definitely something I considered at some point, but I didn't have the time or energy to actually rebuild the container in a way I would prefer to build it. And considering that the initial cost of building the image is just the first step, the container would need to be kept updated too. So definitely beyond my current capacity. That being said, custom image would make things easier with kube-plex and even would be useful for people running standalone Plex.

As for configuration, the bootup process of Plex is rather involved as it runs an init script that prepares some things (at least used to). So you need either copy a config in place on first startup and never again or on the second startup modify the configuration file. (or both.)

I'm happy to add support for additional initContainers to kube-plex if those are needed for this though..

lknite commented 2 years ago

When you get a minute check out what I put together at the plex-config repo.

I've added the main configurations I was looking to have, transcoder throttle buffer, disable network relay, set custom server access urls, and to disable the arrow overlay when pausing a video.

I wouldn't want to get around the initial login, will want to do that through the gui. If I can check that the person is logged in then that'd probably be the time to go ahead and apply the settings. I see a value PlexOnlineUsername which will probably work, my script could wait for that value before performing work. I'll go ahead and add that change.

Not sure where is the best place to run this script. If it were a docker image then I'd just copy the git repo in the dockerfile. That sounds like a lot of work though, I agree. Thinking about it ...

lknite commented 2 years ago

When I get a chance, I'll copy the 'extraVolumes', 'extraVolumeMounts', and 'postStart' template sections from the nextcloud helm chart into kube-plex. Then, I'll see if I can't use a configmap to map the plex-config script and run it with the postStart.

ressu commented 2 years ago

The extra mounts has a small issue with data source, you need to somehow get the contents of the repo into your volume to mount it. A common trick to do that is to use a initContainer that copies the contents (in a similar way as kube-plex does it). You could even reuse the same scratch volume as kube-plex does.

I'm also thinking that it might be more reliable to write the modifier tools in something like Go, so that you can have a single binary that can be used without relying on dependencies within the main container.

lknite commented 2 years ago

I was thinking to maybe write another script which could copy and merge the original and supporting scripts into a single script. Shouldn't be too hard to do, though I suppose it could be said that adds a little complexity. However, once done then it would be a single script would could pretty easily be put into something like a configmap that could be mounted.

I started to lean away from an initContainer as it would have to run before the main container and I'm just not sure how that would work, would the file system even be there for me to modify? Or is all that created when plex first runs?

ressu commented 2 years ago

I would expect that the effort to copy all files vs one file is pretty much the same, so from that point of view it doesn't make a huge difference.

For distributing you have a few options. The configmap option would work through helm where helm would create the configmap when when deploying. You could then mount the configmap into the pod. The downside here is that this is fully dependent on helm and would limit the usefulness of the script.

If you look at how kube-plex works you will see the initContainers solution. The container itself is just providing the compiled binaries and the files are copied to a shared mount

https://github.com/ressu/kube-plex/blob/040f189ef10f1cf58e42d37d7678b6ab3935a7eb/examples/kustomize/base/deployment.yaml#L31-L37

From the shared mount, the files are moved into the correct place.

https://github.com/ressu/kube-plex/blob/040f189ef10f1cf58e42d37d7678b6ab3935a7eb/examples/kustomize/base/deployment.yaml#L82-L88

The same mechanism could be used to deliver the scripts too. This is a more universal solution that doesn't depend on helm or any other tool, but rather depends on features from Kubernetes.

lknite commented 7 months ago

I might still do this, but no need to keep an issue open here.