Plex with GPU transcoding on CasaOS

Koga73
5 min readSep 20, 2024

--

ZimaBoard with an Nvidia GTX 1660 Ti powered by an ATX power supply
ZimaBoard with an Nvidia GTX 1660 Ti powered by an ATX power supply

CasaOS is a Debian based operating system that comes preinstalled on Zimaboard.

Zimboard is a micro-server built on the x86 architecture. It’s great for setting up a personal NAS, firewall and for running Plex server. One feature of the ZimaBoard is it has a PCIe x4 port.

After setting up Plex, I found that it struggled to transcode 4k video. The CPU would max out causing the video stream to buffer. Fortunately Plex supports offloading the video transcoding to hardware. The best hardware to use for this purpose is a graphics card because they support parallel processing via Nvidia Cuda.

The purpose of this post is to document the steps I took to use an NVIDIA GTX 1660 Ti for transcoding in Plex on a ZimaBoard running CasaOS with Plex running in a docker container.

Powering the GPU and ZimaBoard

I am using a GTX 1660 Ti graphics card plugged in to the PCIe x4 port on the ZimaBoard. It’s ok that the port is not wide enough for the card, it doesn’t need the full bandwidth. But it does need external power. For this I used a 400w ATX power supply I had lying around. Just connect the 8-pin GPU cable to the GPU.

I am also using the ATX PSU to power the ZimaBoard which requires 12v DC. The ATX CPU connector has two pairs of 12v / ground wires. I bought a 4-pin CPU extension cable and a 5.5mm x 2.5mm barrel plug. I cut the CPU connector wires and soldered in the barrel plug wires and then wrapped in heat shrink for a completed appearance.

Molex ATX CPU 4-pin EPS connector to 5.5mm x 2.5mm barrel plug
Custom made 12v Molex ATX CPU 4-pin EPS connector to 5.5mm x 2.5mm barrel plug

To keep the power supply on, you can jump two pins or purchase a power supply jumper.

Installing the drivers

Getting the drivers and software working was the hard part. You’ll need to do the following in the terminal on the ZimaBoard. You can use the console on the web interface, SSH into it or directly plug in a keyboard and monitor.

The default username and password for the console is “casaos

  1. Install Kernel Headers
sudo apt install linux-headers-$(uname -r)

2. Blacklist nouveau

The nouveau driver can conflict with NVIDIA, I found it best to blacklist nouveau. This is from the official NVIDIA documentation.

sudo nano /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
sudo update-initramfs -u

3. Update apt sources with “contrib”, “non-free”, “non-free-firmware

sudo nano /etc/apt/sources.list
# Debian 11 "Bullseye"
deb http://deb.debian.org/debian/ bullseye main contrib non-free non-free-firmware

4. Add the production repo for nvidia-container-toolkit

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

5. Install

sudo apt update
sudo apt install nvidia-driver nvidia-container-toolkit

6. Set docker default runtime to nvidia

nano /etc/docker/daemon.json
"default-runtime": "nvidia"

7. Reboot

sudo reboot

8. Verify that the system can see your GPU and the docker runtime

nvidia-smi
sudo docker info | grep -i runtime
CasaOS Nvidia driver confirmation
CasaOS Nvidia driver confirmation

Create the Plex container in CasaOS

CasaOS with Plex container installed
CasaOS with Plex container installed

You will need to create a new container to utilize the GPU regardless of whether you already have Plex setup and running. Note that this uses the Plex image from LinuxServer.io which is preconfigured with the proper drivers.

  1. Click the + button in CasaOS and then “Install a customized app
  2. Then click the import icon
  3. Paste the following for docker-compose.
  4. Be sure to set your PLEX_CLAIM, TZ and configure your volumes
name: plex
services:
plex:
cpu_shares: 90
command: []
container_name: plex
deploy:
resources:
limits:
memory: 7789M
reservations:
devices:
- capabilities:
- gpu
driver: nvidia
count: 1
devices:
- /dev/dri:/dev/dri
environment:
- PLEX_CLAIM=INSERT_YOUR_CLAIM
- TZ=America/New_York
- HOME=/config
- CHANGE_CONFIG_DIR_OWNERSHIP=true
- NVIDIA_DRIVER_CAPABILITIES=all
- NVIDIA_VISIBLE_DEVICES=all
- PGID=1001
- PUID=1001
- VERSION=docker
- PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- TERM=xterm
- LANG=C.UTF-8
- LC_ALL=C.UTF-8
hostname: plex
image: lscr.io/linuxserver/plex:latest
labels:
icon: https://www.plex.tv/wp-content/themes/plex/assets/img/plex-logo.svg
restart: unless-stopped
volumes:
- type: bind
source: /media/nas
target: /data
- type: bind
source: /var/lib/docker/volumes/plex-transcode/_data
target: /transcode
- type: bind
source: /mnt/plex/config/
target: /config
- type: bind
source: /dev/shm
target: /dev/shm
x-casaos:
envs:
- container: TZ
description:
en_us: "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"
- container: PLEX_CLAIM
description:
en_us: "https://www.plex.tv/claim"
image: ""
volumes:
- container: /data
description:
en_us: ""
- container: /transcode
description:
en_us: ""
- container: /config
description:
en_us: ""
ports: []
cap_add: []
network_mode: host
privileged: false
x-casaos:
architectures:
- amd64
author: CasaOS User
category: unknown
description:
en_us: ""
developer: unknown
hostname: ""
icon: https://www.plex.tv/wp-content/themes/plex/assets/img/plex-logo.svg
image: null
index: /web
is_uncontrolled: false
main: plex
port_map: "32400"
scheme: http
store_app_id: plex
thumbnail: ""
title:
custom: ""
en_us: Plex

Configure Plex transcoding

The last step is to ensure that Plex sees the GPU and configure it for transcoding.

  1. Check “Use hardware-accelerated video encoding
  2. Select your GPU as the “hardware encoding device

Additionally I found a nice tip from Jon Simpson which is to configure Plex to utilize the “/dev/shm” ramdisk for the transcoding temporary directory!

Plex — Transcoder settings
Plex — Transcoder settings
ZimaBoard with GPU powered by ATX in rack
ZimaBoard with GPU powered by ATX in rack

--

--