DEV Community

Cover image for A Media Server on Steroids - Walkthrough
Raven Spencer
Raven Spencer

Posted on

A Media Server on Steroids - Walkthrough

Introduction

Good day all, here is the section that keeps me engaged with the current-day readers while also never being more than an extra scroll to people who, also like me, have been looking up other people’s new builds all afternoon (or are interested in how someone creates “the thingamagiggy” to work with the “such-and-such”) and wants to get straight to the actual meat of the article: the experience, or steps.

For this reason, I will keep this brief. (... i.e. skip to the next section)

So, as some of you have seen me post about it on LinkedIn, yes, I got an old family laptop to run a K3S Cluster Jellyfin server application operating through Proxmox. Would I recommend the configuration to others? If they were into making a media server fail-tolerant, upgradeable, scalable, overkill, private (no unnecessary internet access), and cost-effective (practically free or relatively cheap)...

Then yes…

This proof-of-concept setup is for people like me who want the most scalable and future-proofed option, and enjoy their privacy. Also, this is a techie-made build which means it might gloss over some bits deemed unnecessary to go in full depth for brevity. Ha! You thought a full walkthrough meant I would write a 20-page paper with footnotes??

I’m not a masochist… most of the time…

Anyway, let’s talk parts.



image of computer hardware

Obtaining the hardware for a Home Server

In numbered fashion!

  1. An old/unused Laptop or PC [ This will be the server ]. Most any device after 1999 will do, but here is a list of the minimum requirements:
    • 64bit VT CPU (Virtualization-capable)
    • Bare minimum 4 GB RAM
    • Hard Drive - 256GB min → 1+ TB (I also added external storage for media/db files)
    • And an Ethernet jack
  2. An unused USB or removable drive [ This will be used to set up the server OS to Proxmox ].
  3. Two or more Ethernet Cables, for the best connectivity
  4. A home PC with an Ethernet port (the Bastion computer)
  5. And a way to connect to the internet (either directly attaching to the router or using a router connected to an HTTP Proxy like Squid Proxy for passing HTTP requests like I did)
  6. Pick up a router (an easy thrift store buy if one isn’t lying around) be sure it has more than one ethernet jack and can handle Wi-Fi.



private network image

Making a Proxy… Squid-like

— as of December 2024

This step details how to start up a forward proxy if you plan on creating a private network in your home (separate from your home network).

  1. Setup your router and login to the admin page
  2. Check that your computer (or the Bastion) is attached.
  3. Set up your PC with a Static IP (Google ‘How to set up a Static IP... ’ with your specific router name). Remember the Static IP of your PC for later steps

This step involves opening up your private network to the internet when you need to update and operate Kubernetes (K3S).

Download and install Squid for Windows under ‘Console App’ (or Squid for Linux and Mac under ‘Current Squid Release Series → tar.gz’).
Google 'How to install Squid for...' if you need further help installing.

LATER you will configure the /Squid/etc/squid/squid.conf file to allow http_proxy access to the static IP address you configured on the router for your PC. This way, when your PC is hooked to both networks, it can act as a liaison (or the Bastion) between the server and the internet, and not the other way around.



Proxmox logo image

Setting up Proxmox VE

— as of December 2024

This step entails how to create a bootable media to set up an OS, like Proxmox.

  1. Go to the SourceForge Ventoy Download: Ventoy download | SourceForge.net and run the installer (with your USB drive plugged in)
    • Set up and install Ventoy, ISO/Image files can be ‘dragged and dropped’ into the new directory easily without needing to be flashed individually and will run like it was flashed.
  2. Go to the Proxmox website: Downloads - Proxmox Virtual Environment and download the Proxmox image to the Ventoy directory (or flash it)
  3. Eject the USB Drive and plug it into your server (or "Laptop")
  4. Turn the "Laptop" off and connect it to your private router via an ethernet cable.
  5. Turn it on and for Ventoy it should bring you to a boot/GRUB screen with your image as an option. (Else, hit F12 and boot to the USB)
  6. Select and let it boot into the Proxmox VE installation setup page.
  7. Follow the step-by-step process, most of the default settings should be fine. Keep track of your password (the username will be ‘root’ when first logging in).

— (Proxy): When setting up your HTTP Proxy in step 4, put in the Static IP Address of your assigned Squid Proxy or Proxy Server you assigned at the private router step (e.g. 192.168.#.#:3128). Then go to your private router's admin page and set the newly attached server to a new Static IP address. You will also want to configure your /Squid/etc/squid/squid.conf file so that it can accept requests from the Server Static IP. Add acl localnet src <your-server-IP> in the file.

When done with the installation, make sure both your Proxy (or the Bastion) and the server are connected to your private router, then go to your browser and type in your server’s IP address and port 8006, like this: 192.168.#.#:8006. This should bring you to a login page for your Proxmox server.

— Sweet! You are ready for the magic of K3S now!



Booting computer image

Booting up the Ubuntu Servers (VMs) in Proxmox

— as of December 2024

This section is for building the Nodes where K3S will deploy resources and run Jellyfin.

  1. Boot up the 2 VMs [ The first will be the Controlplane Node and the Second will be the Worker Node where Jellyfin will be with the configured port. ].

  2. Go under the server and select ‘Create a VM’ from the top right options, set the RAM to around 1024 - 2000+ and storage at 32 GB as this is all it needs to manage at minimum capacity, and set the image to ‘Ubuntu server’ or set the URL to the latest download link on the official website: Get Ubuntu Server | Download.

    — TIP: Note that Proxmox can’t pull from the internet without a DNS server connection. To rectify this, download the image on your PC and go to the Proxmox server settings ‘Used Images’ to copy it to the server via “drag and drop”. This way it stores the image locally to create VMs.

  3. Name the server something like “controlplane-node01” to keep track of it. Other than that, leave other settings as default and keep track of passwords.

  4. Do the same with the second VM, except name it “worker-node01” and set the RAM limit to 4000 - 6000+ with 50GB.

    • Any other VM made after this should copy step 4. Except, give it a name with a different number like ‘002’ or ‘013’.

— (Proxy): You should also set up your Squid/HTTP Proxy to accept requests from the server IPs which you will have to set as static IPs on your router. Once that is taken care of, you should be able to update your VMs and give Kubernetes access to HTTP by setting the environmental variables HTTP_PROXY and HTTPS_PROXY both to the URL of your PC Squid Proxy: http://192.168.#.#:3128



External drive image

Adding External Storage to your VMs (MORE!!)

— as of December 2024

This step is for setting up the persistent shared storage and is needed if you plan on adding more storage space.

  1. Attach your external storage to the server and mount it to the device using the command line. Google How to mount your storage option if needed.
  2. In the Proxmox web GUI, go under your Proxmox server settings, and on the left panel, click 'Storage' then on the top click 'Add Storage'. Click on the storage type you attach and where it is mounted.
    • Google if you need further instructions on your specific storage type, I used USB haha, but you can even just use space on your system.
  3. After formatting the storage, go to your worker-node VM and click on 'Hardware'. Then click 'Add Hardware', select 'Storage', and add from your attached storage medium.
  4. Afterward, go to your worker-node command line and mount the new storage like in step 1. BE SURE TO MAKE NOTE OF WHERE YOU MOUNT YOUR EXTRA STORAGE (This is important to set up persistent volumes across pods) on the attached storage, also create 2 new directories:
    • One for your media files (/mnt/extra-storage/media)
    • And one for your database and jellyfin configurations (/mnt/extra-storage/data)

Anytime you want to add media, just turn off the Proxmox server, detach the external storage if you went with that, and attach it to your PC to add your media, reattach to server, turn it back on and done! I use the sftp command to add media while the server is on and refresh the Jellyfin library within the admin web GUI. sftp -r <admin-username@worker-node-IP-address> <ON-PC-media-to-upload-folder> <ON-WORKER-NODE-persistent-media-directory>

— Now you are set to install K3S, your lightweight microservices architecture!



K8S image

Installing Lightweight Kubernetes (K3S) on Proxmox

— as of December 2024

This is where the fun begins as K3S is installed on the VMs.

  1. Using the K3S Quick-Start Guide (Quick-Start Guide | K3s), go into the Controlplane Node (VM) command line to install K3S (SSH to copy and paste). Make sure you are connected to the internet or proxy (export HTTP_PROXY="192.168.#.#:3128"). Run curl google.com to test.
  2. Run sudo curl -sfL <https://get.k3s.io> | sh -
  3. Link the Worker Node (VM) to the Controlplane via K3S by going into its command line (check if you have the proxy set up).
  4. Replace SERVERIP with the controlplane node IP and CONTROLPLANENODETOKEN with the controlplane node Token (at /var/lib/rancher/k3s/server/node-token) and run sudo curl -sfL <https://get.k3s.io> | K3S_URL=<https://SERVERIP:6443> K3S_TOKEN=CONTROLPLANENODETOKEN sh -
  5. Now verify by going to the Controlplan Node command line and run sudo kubectl get nodes and the worker VM/Node should be there along with the controlplane node.



jellyfin banner image

Prepping the Jellyfin K3S Deployment

— as of December 2024

Time to start running the Kubernetes environment!

  1. SSH into the controlplane node and clone this template on my GitHub git clone RavenEsc/jellyfin-k8s-deployment, or wget <my-repo> and inflate the tarball. Again, ensure you can connect to the internet: curl google.com. MAKE SURE YOU ARE RUNNING COMMANDS IN THE DIRECTORY, cd jellyfin-k8s-deployment.
  2. If you want to easily set up the variables, install Helm and proceed to part “A”. If you want to run the K3S files directly with Kubectl, move to part “B”.

    A.

    Go to “./jellyfin-charts/values.yaml” and edit the following variables. (labeled as “# !!” in the file)

    • nodeSelector.kubernetes.io/hostname, set to the name of your worker node
    • dataVolumeConfig.storage, set this to “100Gi” minimum
    • dataVolumeConfig.hostPath, set this to the path that you want to store the jellyfin data files (this is the same path where you store your data files on the mounted storage medium with Proxmox)
    • mediaVolumeConfig.storage, set this to how much space you wanted for the media, I did “800Gi”
    • mediaVolumeConfig.hostPath, set this to the path that you want to store your media files (this is the same path where you store your media files on the mounted storage medium with Proxmox)

    Run helm install jellyfin ./jellyfin-charts --namespace jellyfin --create-namespace (You can use the --dry-run and --debug option to test before deploying)

    B.

    After setting these environmental variables with export:

    • WNODENAME=<your-worker-node-name>
    • DATASTORAGE=<your-data-path-storage-size>
    • DATAPATH=<your-data-path>
    • MEDIASTORAGE=<your-media-path-storage-size>
    • MEDIAPATH=<your-media-path>

    Run the custom bash script with: chmod +x ./jellyfin-k8s-deployment/ykvar.sh && ./ykvar.sh -nv (Be sure to check if the variables changed cat ./k8s/deploy/jellyfindeploy.yaml).
    Then run sudo kubectl create -Rf ./k8s (You can use the --dry-run=client to test before deploying)
    — TIP: The ykvar.sh script has options, so check them out with ./ykvar.sh -h help option.

  3. Check that the deployments are running with sudo kubectl get deploy -n jellyfin-server ( Deployment should be 1/1 ).

  4. Check that the service is up with sudo kubectl get svc -n jellyfin-server ( Service should be accessible by the configured port 30096 on the Static Worker Node/VM IP. You can check by typing in the IP and port number into your PC browser and a Jellyfin page should come up if the Pod is up ).

  5. Check if the Persistent storage is up with sudo kubectl get pv -n jellyfin-server and if the Claim from the deployment is attached with sudo kubectl get pvc -n jellyfin-server (Look to see that both are up and they say, under the "STATE" field, “BOUND” )



testing infrastructure image

Test the K3S Jellyfin Server running on Proxmox

— as of December 2024

  1. Go into the Jellyfin Web GUI and set up the server with the quickstart (save passwords).
  2. Add some media, if you do not have media on your server, simply add it to the persistent media storage path mounted before. Utilize a transfer tool like SFTP to send the media from your PC to your Worker-Node IP over the network.
  3. Set the media directory up as a media library (organized however you want it) and try viewing the media and its impact on your worker node with the resource usage visualizer on Proxmox’s VM summary page.
  4. After all goes well, it’s time to test durability. Delete the current deployment pod with 'sudo kubectl delete pod/jellyfin-deployment-##########-##### -n jellyfin' replacing the pod name with the current pod up which can be found with 'sudo kubectl get pod -n jellyfin'.
    • After it is deleted, check if a new pod took its place with 'sudo kubectl get pod -n jellyfin'. (If not, check if your Proxy is up as it needs a connection to access the jellyfin image)
    • If so, refresh the Jellyfin page on your PC and either a login page or a “select server” screen will pop up. Give the service inside the Pod time to reconfigure (at most 5 minutes) then either select the server and hit "connect", it should bring you to sign in, and/or log in with your username and password. After that, you will be greeted with the home page and all of your media where it was if it functioned properly.

If not, look below or ask in the comments section if needed. Running on limited resources or old hardware might have weird outcomes. When in doubt, Google or DuckDuckGo or whatever you use.



finished server image

Done! General Challenges

— as of December 2024

As you may have noticed, Jellyfin is not built to be a multi-tier application. I ran into some roadblocks while developing this solution as I would need to change the Jellyfin source code and make my own container image (which would probably not be reasonable to upkeep without a high demand or a team). And although I want to make the best of the best before anyone sees it, I want to open this up to the world as a “look how far it's come”! I am also reminded not to let things go on too long before asking for criticism. The intention of this walkthrough was to share the work I have done and hopefully get to inspire others in their paths. Was making a K3S cluster on a single old laptop with limited resources overkill?

Yes, absolutely.

But I wanted to make a solution that was not only able to use our extra devices but also had the option to scale if someone wanted to. Proxmox is great at that, and K3S isn’t the end. You could add more devices and make a makeshift server rack. Make it even more secure by utilizing Jellyfin’s HTTPS port, or find some way to keep sessions and profile preferences persistent so you can run more than 1 pod at a time (trust me, I’m trying)! You could even turn this into a cloud-based or remote configuration with secure and accessible storage and viewing options! For now, I am happy with where it is, and so are my users!

Overall, I am glad to have tried and I hope you have found this as interesting as I have.

Oh, and to the people just here for the “How to…” and “Is it possible to make…” google searches,


sup.

Top comments (0)