DiyMediaServer
Featured image of post How to Install Docker on Debian for GPU Passthrough and Transcoding

How to Install Docker on Debian for GPU Passthrough and Transcoding

A Practical Guide to Docker GPU Passthrough on Home Servers

You want buttery-smooth 4K to 1080p hardware transcoding, and the quiet satisfaction of watching your CPU lounge around at 10% while your GPU does the heavy lifting. So you pass your GPU into a Docker container, and Jellyfin stares back at you with the enthusiasm of a DMV clerk. CPU’s pegged. Jellyfin’s logs throwing a tantrum about “no such device /dev/dri/renderD128.”

Welcome to the club. Population: everyone who has ever tried this.

I once burned a perfectly good Friday night (116 minutes, to be precise) wrestling with what Docker’s documentation cheerfully calls “simple” GPU passthrough. Drivers? Rock solid. Docker daemon? Restarted three times, because why stop at two. YAML file? Formatted with the precision of a Swiss watchmaker. The actual problem? Linux permissions had decided my container wasn’t ‘special’ enough for the render group’s exclusive party.

After a scenic tour through udev rules, cgroup mysteries, and two spectacularly wrong Reddit threads that shall remain nameless, the GPU finally woke up. Frame times dropped from “slideshow” to “silk.” My CPU went back to napping. And I made myself a promise to document this mess before my brain forgot the crucial details.

This is that documentation. The step-by-step guide I needed that night. You’ll get the exact Docker Compose configuration, the permissions that actually matter, and a heads-up about the gotchas that love to bite newcomers. Whether you’re on NVIDIA, Intel integrated graphics, or AMD, by the end of this you’ll have hardware-accelerated transcoding humming inside Docker. No 1 AM debugging session required.

πŸ’­ TL;DR
Think Docker will magically use your GPU? Cute. NVIDIA needs --gpus, Intel/AMD need /dev/dri, and you need to join the right groups. Otherwise, enjoy watching your CPU sweat bullets.
ASRock Intel ARC A380 Challenger: The Arc A380 isn't for gamingβ€”it’s for obliterating video streams. With support for H.264, HEVC, and full AV1 hardware enco…

ASRock Intel ARC A380 Challenger The Arc A380 isn’t for gamingβ€”it’s for obliterating video streams. With support for H.264, HEVC, and full AV1 hardware encode/decode, it crushes 20+ 1080p streams or 6–8 HDR tone-mapped 4Ks without breaking a sweat. Drop it in your media server, give Jellyfin direct VA-API access, and watch your CPU finally cool off for a bit.

Contains affiliate links. I may earn a commission at no cost to you.

That card up there is what I’d buy today if I was starting fresh. But the box won’t help you if Docker can’t see it. So let’s talk about why this whole setup falls over so often.

Why GPU Passthrough Matters

Video transcoding hammers a CPU. Hardware acceleration through GPU features (NVIDIA NVENC, Intel VAAPI/QSV, AMD VCE) moves that work off the CPU, drops your load average, and quiets the fans.

Docker lets you isolate Jellyfin or Plex in a container while still handing the GPU through in a controlled way. You get smoother streams, more simultaneous viewers, quieter hardware, and an idle CPU that finally earns its sleep state.

One thing to keep straight: GPU passthrough in Docker is not the same as VM passthrough. Docker leans on device permissions and cgroups to share a GPU between host and container. It’s nowhere near as involved as full hardware virtualization through PCIe passthrough on a hypervisor.

Why GPU Passthrough in Docker on Debian Often Fails (And How to Fix It)

Here’s the thing about GPU passthrough with Docker on Debian or any other Linux distro. It’s conceptually clean and practically finicky. Your GPU lives on the host, happily managed by kernel drivers. Your container exists in its own isolated environment with its own filesystem and permissions. Getting Docker and your GPU to talk takes more than mounting a device file. You need the right permissions, the correct device nodes, and sometimes a few udev rules to make everything line up.

Think of it like lending your car to a friend. Handing over the keys (mounting the device) isn’t enough. They need insurance coverage (permissions), they need to know where it’s parked (device paths), and they need to understand the quirks (Linux-specific device behaviors).

Common failures: your container sees the GPU but has no permission to use it, missing device nodes make the GPU invisible, or everything works until a reboot shuffles the device paths and breaks the mapping.

Let’s fix all of that and get Docker GPU passthrough working reliably.

Need a Linux permissions refresher?
Understanding Linux Permissions

Proper Docker Compose Configuration for GPU Passthrough on Debian

Forget juggling docker run -it commands with a wall of flags. Here’s a straightforward Docker Compose setup for GPU passthrough that survives Debian reboots:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin-hw
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128  # GPU device access
    group_add:
      - "render"           # Add container user to render group
      - "video"            # Add container user to video group
    environment:
      - JELLYFIN_PublishedServerUrl=http://your-server-ip:8096
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /path/to/media:/media:ro
    ports:
      - "8096:8096"
    restart: unless-stopped

Why this works:

  • devices: /dev/dri/renderD128:/dev/dri/renderD128 hands the render node into the container, which is what VA-API needs.
  • group_add puts the container user in the render and video groups so the device permissions actually let it through.
  • restart: unless-stopped brings Jellyfin back after a reboot or a crash, instead of leaving you to notice at 11 PM.

NVIDIA vs Intel/AMD GPU Passthrough on Docker

NVIDIA: Simplified GPU Passthrough

Install the proprietary NVIDIA driver and the NVIDIA Container Toolkit on Debian. Then use docker run -it --gpus all or the Compose device_requests block. The toolkit handles the driver mapping and permissions for you.

Good fit for transcoding, AI workloads, or anything else that wants CUDA.

Intel/AMD: Manual Device Mapping

For Intel and AMD on Debian, you do the work yourself. Expose /dev/dri to the container, manage the permissions, and make sure the right drivers are installed (intel-media-va-driver, mesa-va-drivers).

Add the container user to the render and video groups or you’ll spend an hour debugging Permission denied errors. Once it’s wired up, this approach is rock-solid for transcoding.

Preparing Your Debian Host for Docker GPU Passthrough

Before you touch Docker, prove the GPU works on the host. If vainfo or nvidia-smi doesn’t see it from the bare metal, no amount of YAML will help you.

NVIDIA Setup on Debian

  1. Install the NVIDIA proprietary drivers. Verify with nvidia-smi.
  2. Install the NVIDIA Container Toolkit:
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
  1. Verify with:
docker run --rm --gpus=all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

Intel iGPU Setup

  1. Confirm the i915 kernel driver is loaded:
lsmod | grep i915
  1. Check that /dev/dri device nodes exist (ls -l /dev/dri/).
  2. Install VA-API drivers:
sudo apt install intel-media-va-driver vainfo
  1. Run vainfo and look for a populated profile list. An empty list means the driver isn’t loading.

Docker and Docker Compose Requirements for GPU Passthrough on Debian

  • Docker version 20.10 or newer (check with docker --version)
  • Docker Compose V2 (docker compose, not the legacy docker-compose)
  • A Linux kernel with cgroup v2 enabled

NVIDIA users need the runtime wired up through nvidia-container-toolkit. Intel and AMD users only need correct device mapping and group membership.

Correct GPU Passthrough Configuration with Docker Compose on Debian

⚠️
Warning: I do not use NVIDIA or AMD hardware in my lab. Everything NVIDIA or AMD related in this post is straight from the documention.

NVIDIA Compose Example:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    ports:
      - "8096:8096"
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/media:/media
    restart: unless-stopped
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

Intel/AMD Compose Example:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128
    user: "1000:1000"  # Adjust to your host user UID:GID
    group_add:
      - "render_gid"    # Replace with actual host render group GID
      - "video_gid"     # Replace with actual host video group GID
    ports:
      - "8096:8096"
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/media:/media
    restart: unless-stopped

Grab the right group IDs from the host with getent group render and getent group video. Drop the numeric GID into group_add in place of render_gid and video_gid. If you run a beefier Arc card, the same Compose file applies and you get more headroom for parallel streams.

Sparkle Intel Arc B580 Titan: The Intel Arc B580 is a transcoding powerhouse, with full hardware support for AV1, HEVC, VP9, and H.264 plus 12 GB of VRAM for smooth multi-stream 4K/8K workflow

Sparkle Intel Arc B580 Titan The Intel Arc B580 is a transcoding powerhouse, with full hardware support for AV1, HEVC, VP9, and H.264 plus 12 GB of VRAM for smooth multi-stream 4K/8K workflows. Its 160 XMX AI engines turbocharge upscaling and media conversions, making it perfect for Plex, Jellyfin, or Docker-based media servers.

Contains affiliate links. I may earn a commission at no cost to you.

Once the Compose file is in place and the GPU is wired through, the only thing left is troubleshooting whatever the first docker compose up -d throws at you.

Resolving Common GPU Passthrough Issues on Debian with Docker

  • no available runtime or could not select device driver means the NVIDIA Container Toolkit isn’t installed or the daemon hasn’t been restarted since you configured it.
  • no such device /dev/dri/renderD128 means the device nodes aren’t mapped, or the GPU drivers aren’t loaded on the host. Run ls -l /dev/dri/ to confirm.
  • Permission denied errors almost always trace back to missing group_add for render and video. Double-check the numeric GIDs match the host.
  • After a kernel update, device numbering can shift. Use a udev rule to pin permissions, or symlink /dev/dri/renderD128 so the path stays stable.

Verifying GPU Access Inside Your Docker Container

  • For NVIDIA: docker run --rm --gpus=all nvidia/cuda nvidia-smi. You want to see your card listed.
  • For Intel/AMD: docker run --rm --device /dev/dri:/dev/dri jrottenberg/ffmpeg ffmpeg -hwaccels. Look for vaapi or qsv in the output.

If those work from a throwaway container, your Compose file will work too.

Real-World Example: Jellyfin GPU Passthrough on Debian

NVIDIA-enabled Jellyfin:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/media:/media
    ports:
      - "8096:8096"
    restart: unless-stopped
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

Intel iGPU Jellyfin:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128
    user: "1000:1000"
    group_add:
      - "render_gid"
      - "video_gid"
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/media:/media
    ports:
      - "8096:8096"
    restart: unless-stopped

After the container is up, head into Jellyfin’s Dashboard, open Playback, and switch hardware acceleration to VA-API (Intel/AMD) or NVENC (NVIDIA). Set the render device to /dev/dri/renderD128 for VA-API. Play a 4K file from a phone or browser and watch intel_gpu_top or nvidia-smi dmon light up on the host. If the host stays quiet and the CPU spikes, transcoding is still landing on software.

Final Tips for Installing Docker on Debian and Running GPU Passthrough on Raspberry Pi and Home Servers

  • Always verify GPU functionality on the host before you touch Docker.
  • Install Docker on Debian from the official repositories or Docker’s install script.
  • Use docker run -it with --gpus for a quick smoke test on NVIDIA before you commit to a Compose file.
  • A Raspberry Pi 4 or 5 has no useful video encoder for modern codecs. If you want serious Jellyfin transcoding, run it on x86 with an Intel iGPU or a discrete Arc card. The NUC below is the small-footprint version of that recommendation.

Run those steps in order and you’ll have hardware-accelerated transcoding working inside Docker on Debian.

Other Resources

Happy transcoding with Docker.

Intel NUC 12 Pro (NUC12WSHi5): Compact mini PC for lightweight servers, GPU Passthrough, Docker stacks, and VMs.

Intel NUC 12 Pro (NUC12WSHi5) Compact mini PC for lightweight servers, GPU Passthrough, Docker stacks, and VMs.

Contains affiliate links. I may earn a commission at no cost to you.

Was this useful?

Last updated on May 20, 2026 06:56 MDT