Enabling Hardware Acceleration for Jellyfin on Talos Linux (Using Onedr0p Cluster-Template)


Sat May 17 2025
| 5 min read
|
Philip Rutberg Philip Rutberg

Jellyfin on Talos Linux

In my homelab journey, I've embraced Kubernetes for everything from running Jellyfin media servers to home automation and beyond. Central to my setup is a Kubernetes cluster running on Talos Linux, managed declaratively through Flux CD. I've been using the fantastic onedr0p cluster-template, a GitOps-driven, batteries-included template that leverages Talos.

Recently, I faced a common challenge: enabling hardware acceleration for Jellyfin running on nodes powered by Intel integrated GPUs (iGPU). This feature dramatically reduces CPU usage during media transcoding. After some back-and-forth experimentation and learning, I successfully enabled iGPU acceleration through system extensions provided by Talos's new “System Extensions” functionality.

In this guide, I share everything I learned, broken down into clear steps you can follow to replicate the setup smoothly, even if you're new to Talos or the onedr0p cluster-template.

What You'll Learn in This Guide

  • Building a custom Talos installer image via Talos Image Factory
  • Integrating Talos system extensions (specifically i915 for Intel iGPUs)
  • Declaratively managing Talos nodes with onedr0p's cluster-template
  • Configuring Jellyfin for hardware-accelerated transcoding
  • Validating and troubleshooting your setup

Prerequisites

  • A running Talos Linux cluster
  • Nodes equipped with Intel iGPUs (e.g., UHD 630 on Dell OptiPlex Micro)
  • Jellyfin deployed in Kubernetes (preferably via Flux)
  • Basic familiarity with the onedr0p cluster-template workflow

Step-by-Step Guide

Important Note on Upgrading Talos

This guide also covers the scenario of upgrading Talos Linux from an older version (like 1.9.5) to a newer version (like 1.10.0). All the steps outlined here will seamlessly guide you through the upgrade process alongside enabling hardware acceleration.

Step 1: Building a Custom Talos Installer Image (via Talos Image Factory)

Head over to the official Talos Image Factory to build a tailored installer image:

  • Choose the desired new Talos version to upgrade to (e.g., from 1.9.5 to 1.10.0) or use the same version your nodes are currently running if you prefer not to upgrade.
  • Under System Extensions, select:
    • siderolabs/i915 (GPU driver)
    • siderolabs/intel-ucode (optional but recommended microcode update)
  • Click Create and copy your generated schematic ID.

The Factory will provide an image URL similar to:

factory.talos.dev/installer/<your-schematic-id>:v1.10.0

Step 2: Integrate the Custom Installer with Onedr0p Cluster-Template

Update your nodes.yaml file with the schematic ID you generated:

nodes:
  - name: talos-1
    address: <your-ip-address>
    controller: true
    disk: <your-disk>
    mac_addr: <your-mac-address>
    schematic_id: <your-schematic-id> # Update with the new Schematic ID received by the Talos Image Factory
  - name: talos-2
    address: <your-ip-address>
    controller: true
    disk: <your-disk>
    mac_addr: <your-mac-address>
    schematic_id: <your-schematic-id> # Update with the new Schematic ID received by the Talos Image Factory
  - name: talos-3
    address: <your-ip-address>
    controller: true
    disk: <your-disk>
    mac_addr: <your-mac-address>
    schematic_id: <your-schematic-id> # Update with the new Schematic ID received by the Talos Image Factory

Commit and push your changes.

Step 3: Regenerate the Cluster Configurations

task configure
task talos:generate-config

Ensure the installer image URL is correctly updated in talos/clusterconfig/talconfig.yaml:

nodes:
  - hostname: 'talos-1'
    # ...
    talosImageURL: factory.talos.dev/installer/4b3cd373a192c8469e859b7a0cfbed3ecc3577c4a2d346a37b0aeff9cd17cdb0 # You should see your new image URL here
  - hostname: 'talos-2'
    # ...

Step 4: Roll Out the Upgrade (Node-by-Node so nothing explodes)

This step will also perform the actual Talos version upgrade (e.g., from 1.9.5 to 1.10.0), ensuring your nodes run the desired Talos version after completion.

Safely upgrade your nodes one-by-one (starting with controllers if you have multiple):

kubectl drain talos-1 --ignore-daemonsets --delete-emptydir-data # Drain the node from any workloads
task talos:upgrade-node IP=<IP> # Upgrade the node, this will use the new image
talosctl health -n <IP> # Check health, you should see "Healthy" status and an error telling us to uncordon the node
kubectl uncordon talos-1 # Uncordon the node

Repeat for each controller and worker nodes.

Step 5: Verify iGPU Drivers on Talos Nodes

Once the node is upgraded and rebooted, confirm everything loaded correctly:

talosctl -n <IP> get extensions | grep i915 # Should show "running"
talosctl -n <IP> ls /dev/dri # renderD128 should appear

Test VA-API capabilities directly from the Talos node:

talosctl -n <IP> containers exec -- \
  vainfo --display drm --device /dev/dri/renderD128

Expect to see H.264 and HEVC capabilities with driver iHD.

Note

If you encounter issues related to the vainfo command, ensure you have the necessary packages installed. You can do this by running the following within the container:

apt-get install vainfo

Step 6: Configure Jellyfin for Hardware Acceleration

In Jellyfin's Web UI:

Admin Dashboard > Playback > Transcoding

Configure as follows:

OptionRecommended Setting
Hardware accelerationVA API / Intel QSV
Device/dev/dri/renderD128
Enable hardware decodingH.264, HEVC (H.265), VP9
Enable hardware encoding
HEVC encodingOptional (depends on clients)
Allow 10-bit HEVC
VPP Tone-mapping
Transcode temporary path/cache/transcodes
Max simultaneous transcodes2

Step 7: Test Jellyfin HW Acceleration

Play a 4K HEVC file from a device forcing transcoding (e.g., Safari on iOS). In Jellyfin's Dashboard > Activity, you should see:

  • VAAPI (hw) or QSV (hw) for both decode and encode.
  • CPU usage should be significantly lower (< 15%).

Check live ffmpeg logs if needed:

kubectl logs <jellyfin-pod> -f | grep ffmpeg

Troubleshooting

Common Issues and Solutions

  • Missing /dev/dri/renderD128: Ensure the Talos node correctly loaded siderolabs/i915 and rebooted after upgrade.
  • vainfo errors inside Jellyfin container: Install VA-API libs:
apt update && apt install -y intel-media-va-driver-non-free
  • “Software” instead of “(hw)” in Jellyfin: Double-check Jellyfin settings and codecs selections as outlined.
  • Issues upgrading Talos versions (e.g., schema validation errors in talhelper): Ensure your talhelper version is up-to-date and compatible with the new Talos version schema.

Final Thoughts & Lessons Learned

Leveraging Talos system extensions to enable iGPU transcoding was a bit challenging at first, primarily due to understanding the Talos Image Factory and how extensions work declaratively. However, using the onedr0p cluster-template's structured workflow greatly simplified the integration.

Now, with Jellyfin smoothly transcoding using hardware acceleration, CPU usage is dramatically reduced, providing a significantly better streaming experience and cooler-running hardware. This experience not only solved a practical need but also taught me valuable insights about declarative management of system extensions within the Talos ecosystem.

I hope this detailed guide helps you achieve the same results in your homelab or projects!

Happy homelabbing, Philip Rutberg 🚀