Apps & Software

Jellyfin Setup: Docker, Transcoding, Remote Access

Jellyfin setup on Docker: the compose file that works, the hardware choice that decides everything, file naming, and how to reach it from outside safely.

Jellyfin setup — Docker compose, hardware transcoding, library naming, remote access

⚡ The short version

Jellyfin installs in about a minute; three decisions around it are what make it usable. Hardware decides whether transcoding works or your CPU melts. File naming decides whether the library identifies itself or you spend an evening fixing posters. Remote access decides whether the server is private or on the public internet. The container is the easy part.

You can have Jellyfin running before the kettle boils. Whether it is any good to live with depends on choices you make before and after that, and almost none of them are in the install command.

This is the Jellyfin setup I would give someone starting today: what the hardware has to be able to do, the compose file that actually works, how to name files so the scanner recognises them, how to switch on hardware transcoding, and how to get to it from outside the house without putting a media server on the open internet. If you are still deciding between servers, Jellyfin vs Plex is the comparison; this is what happens after you pick.

What You Are Actually Installing

Jellyfin is a media server: it indexes your files, fetches metadata for them, and streams them to apps on your phone, TV and browser. It is licensed GPL-2.0, and the project’s README puts its position plainly — “no strings attached, no premium licenses or features, and no hidden agendas”. Hardware transcoding and remote access are not upsells here, which is the whole difference from Plex.

The client story is better than it was. The project ships first-party apps for Android, Android TV and Fire TV, iOS, Roku, LG webOS, Samsung Tizen and Xbox, plus a desktop player and Kodi add-ons — and its client list now points at a Samsung TV App Store page for Tizen rather than a sideloading guide, which is worth knowing if you last looked a couple of years ago. The honest gap: no first-party Chromecast client. Google TV devices run the Android TV app instead.

The Hardware Decision Comes First

Direct play — the client just plays the file — costs the server almost nothing. Transcoding, where the server decodes the video and re-encodes it to fit the client or the connection, is the expensive path, and something always triggers it eventually: a phone on mobile data, a TV that cannot handle the audio track, a 4K HDR file going to a 1080p screen.

Jellyfin’s documentation is unusually blunt about this. It says a server without a GPU is not recommended, and that “depending on your configuration, you may end up in situations where a Ryzen 9 5950X cannot handle even a single video stream”. That is the project telling you a fast CPU is not a substitute.

Hardware What Jellyfin’s docs say (checked 31 Aug 2026) Verdict
Intel N100 or 12th-gen and newer with integrated graphics Recommended, and named as the low-power pick The default choice
Intel 7th-10th gen integrated graphics Still capable; removed from the recommended list because Intel deprecated the toolkit Fine if owned, not worth buying
Raspberry Pi and most single-board computers “Too slow to provide an acceptable Jellyfin experience”, the Pi 5 called out by name Direct play only
Prebuilt NAS appliances Often low-end CPUs, and third-party software is harder to install Check the CPU before you trust it
AMD integrated graphics “NOT recommended”, and the same warning applies on Linux Avoid for this job

If you are buying, a small Intel box is the boring right answer — see the mini PC guide for what that costs. If you already own a Pi, run it and accept the limit: it serves files that play as-is, which is exactly the conclusion the Raspberry Pi guide reaches. If your media lives on a NAS, check its processor against the list above before assuming the built-in app store version will transcode; the NAS buying guide has the hardware detail.

One more number from the same page: the docs suggest at least 20 Mbps of upload bandwidth for remote access, and if your total upload is under 100 Mbps, capping Jellyfin at 70% of it in the dashboard so the rest of the house still works.

Installing Jellyfin with Docker Compose

The official image is jellyfin/jellyfin, also published as ghcr.io/jellyfin/jellyfin. This is adapted from the compose file in Jellyfin’s own container documentation:

services:
  jellyfin:
    image: jellyfin/jellyfin:10.11
    container_name: jellyfin
    user: 1000:1000
    ports:
      - 8096:8096/tcp
      - 7359:7359/udp
    volumes:
      - ./config:/config
      - ./cache:/cache
      - type: bind
        source: /srv/media
        target: /media
        read_only: true
    restart: unless-stopped

Three lines there are worth understanding rather than copying. user: 1000:1000 runs the server as your own account instead of root, so the files it writes are ones you can manage; check yours with id -u and id -g. Port 8096 is the web interface, and UDP 7359 is local client discovery — how the TV app finds the server without being told an address, useful on your LAN and meaningless outside it. Mounting the library read_only: true costs nothing, because Jellyfin never needs to write there, and means a misconfigured scan cannot touch your files.

Start it, then open http://your-server-ip:8096 and work through the wizard:

docker compose up -d

Containers on Windows or macOS are unsupported. Jellyfin's documentation says so directly, and names hardware transcoding as one of the things known to break. On those machines install the native package instead. This guide assumes a Linux host, which for most people means a mini PC, a NAS or a VPS.

If the compose syntax is unfamiliar, the Docker guide covers volumes, published ports and update habits in more detail. Podman works too — Jellyfin documents it alongside Docker.

Name the Files the Way Jellyfin Reads Them

Most “Jellyfin can’t find my media” problems are naming problems. The scanner matches folder and file names against metadata providers, and it is stricter than you would guess.

Movies go one folder per film, with the video file named the same as its folder:

Movies
├── Arrival (2016)
│   └── Arrival (2016).mkv
└── Dune (2021) [imdbid-tt1160419]
    └── Dune (2021) [imdbid-tt1160419].mkv

The year is optional but resolves most collisions. The provider id in brackets is the escape hatch for the rest: two films with the same title and year stop being a coin toss.

Shows go series folder, then season folder, then episodes tagged S01E01:

Shows
└── Severance (2022)
    ├── Season 01
    │   ├── Severance S01E01.mkv
    │   └── Severance S01E02.mkv
    └── Season 02
        └── Severance S02E01.mkv

Keep movies and shows in separate libraries, each pointed at its own folder — Jellyfin copes with a mixed folder, but identification gets worse for no gain. After a rename, run Scan Library Files from the dashboard; the scan picks up the change, a restart does not.

Hardware Transcoding Is the Setting That Matters

Nothing above enables transcoding. The container cannot see your GPU until you pass the device through, and Jellyfin will not use it until you turn it on in the dashboard. Both steps are needed, and skipping the second is the common mistake.

On an Intel box, find the group that owns the render device and add the container to it:

getent group render | cut -d: -f3
ls -l /dev/dri

Then extend the service with the group id that command printed:

    group_add:
      - '992'   # whatever getent printed on your host
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128

On some distributions the group is video or input rather than render; the ls -l /dev/dri output tells you which. After docker compose up -d, confirm the container can actually see the hardware before touching the dashboard:

docker exec -it jellyfin /usr/lib/jellyfin-ffmpeg/vainfo

That command lists the codec profiles the GPU exposes. If it errors, the passthrough is wrong and no dashboard setting will rescue it. If it works, go to Dashboard, then Playback, and set hardware acceleration to Intel QuickSync or VA-API, then untick any codec your GPU does not list.

The transcoder has to be Jellyfin's own build. The project maintains a fork, jellyfin-ffmpeg, and its documentation warns that FFmpeg binaries from anywhere else give you partial acceleration at best. The official Docker image ships the right one along with the Intel media drivers, which is the main reason to start there rather than with a third-party image.

Reaching It From Outside the House

Jellyfin does not expose itself, and its networking documentation is direct about the naive approach: opening a port straight to the internet is “insecure and not recommended”. A media server holds your library and your family’s accounts, and it speaks plain HTTP by default.

Two approaches are worth your time. A private network like Tailscale puts your devices on one encrypted network with nothing published publicly — Jellyfin documents this itself, and notes it works where a port cannot be forwarded at all, such as behind carrier-grade NAT. The trade is that every device needs the client, which rules out a TV app you cannot install software on. A reverse proxy is the other route: one public entry point with a real certificate, a subdomain, and the server itself never directly addressable. That is what you want if people outside your household use the server. A third route, Cloudflare Tunnel, needs no open port at all — but Cloudflare’s terms restrict serving video through a public hostname on the free plan, so it is the one option here that Jellyfin specifically does not fit.

⚠️ Publishing a port in Docker steps around UFW. The ports: line above puts 8096 on your LAN, which is what you want at home. It is also why a server that looks firewalled can answer from the internet the moment the router forwards to it — the rule you wrote never applies. The server hardening guide explains the bypass and what to do instead.

Whichever you choose, leave UDP 7359 alone. Discovery is a local convenience and the documentation is clear that it should not be exposed externally.

Which Version to Install, and What to Pin

The stable line is 10.11. Checking the tags in Jellyfin’s repository on 1 September 2026, the newest stable tag is v10.11.11, dated 6 June 2026; 10.11.0 itself shipped in October 2025. The next major release is 12.0 — the project is dropping the never-changing “10” prefix, so there is no 10.12 — and it is in release candidates, the newest being v12.0-rc7 dated 31 August 2026.

That is why the compose file above pins 10.11 rather than latest. Jellyfin’s tag scheme is documented: latest follows the newest stable release including major version bumps, while X.Y stays on that minor line. Pinning means 12.0 arrives when you decide, after a backup, rather than on whichever evening you happened to run a pull.

One footnote for old hardware: from 10.11 onwards, Jellyfin requires a CPU supporting SSE4.1 — Intel Penryn (Q4 2007) or newer, AMD Bulldozer (Q4 2011) or newer. If you were planning to repurpose something older than that, it will not run.

Frequently Asked Questions About Jellyfin Setup

Is Jellyfin completely free?

Yes. Jellyfin is licensed GPL-2.0 and its README states there are no premium licenses or features. Hardware transcoding, remote access and every official client app are included, because there is no paid tier to put them behind. Your costs are the machine it runs on and the electricity it uses.

Do I need a GPU to run Jellyfin?

You need one to transcode, which most households end up doing. Jellyfin’s own hardware guidance says running without a GPU is not recommended and warns that depending on the file, even a fast desktop CPU can struggle with a single stream. An Intel chip with integrated graphics is enough and is what the project recommends first.

Why does Jellyfin show the wrong movie for my file?

Almost always the folder name. Jellyfin identifies a movie from a folder named Movie Name (year), with the video file inside carrying the same name. Adding the provider id, as in Movie Name (2019) [imdbid-tt1234567], settles the case where two films share a title. Fix the name, then run Scan Library Files again.

Should I use the official image or the LinuxServer one?

Start with the official jellyfin/jellyfin image. It ships the jellyfin-ffmpeg build and the Intel media drivers that hardware transcoding needs, and it is what the documentation assumes. The Jellyfin docs also note that the config and data paths differ between the official and LinuxServer images, so the two cannot be swapped without moving files.

How do I watch Jellyfin outside my home network?

Not by forwarding port 8096 at the router, which the Jellyfin networking documentation calls insecure and does not recommend. Use a private network such as Tailscale, which also works behind carrier-grade NAT, or put a reverse proxy with a real certificate in front of the server. Client discovery on UDP 7359 is local only and should never be exposed.

Should I install Jellyfin 12 or stay on 10.11?

Stay on 10.11 unless you are testing. As of 1 September 2026 the newest 12.0 tag in the Jellyfin repository is a release candidate, rc7, dated 31 August 2026, while the stable line is 10.11 with 10.11.11 tagged on 6 June 2026. Pin the image tag to 10.11 so the eventual 12.0 release does not upgrade your server the next time you pull.

The Bottom Line

🎬 Takeaway: The install is a compose file; the setup is three decisions. Get hardware right first — an Intel iGPU transcodes, a Pi does not, and Jellyfin's own docs say so. Get naming right second, because the scanner reads folders, not intentions. Get remote access right third, through Tailscale or a reverse proxy, never a forwarded port. Pin the tag to 10.11 while 12.0 is still in release candidates.

How This Guide Was Researched

Checked against primary sources on 31 August 2026, with the version tags re-checked on 1 September 2026:

  • Version state from the tags in the jellyfin/jellyfin repository, read with git ls-remote: v10.11.11 is the newest stable tag, its commit dated 6 June 2026, and v12.0-rc7 the newest 12.0 tag, dated 31 August 2026. The jump from 10.11 to 12.0 and the dropped prefix come from Jellyfin’s State of the Fin posts of 6 January and 24 May 2026
  • Compose file, image names, tag semantics, port bindings, media naming, the Windows and macOS container warning, the LinuxServer path difference, the hardware guidance quoted above, the SSE4.1 requirement, the 20 Mbps upload figure and the device passthrough steps all from Jellyfin’s official documentation, read as markdown from its source repository at github.com/jellyfin/jellyfin.org
  • Licence and the “no premium licenses or features” wording from the LICENSE and README files in the Jellyfin repository
  • No transcoding benchmarks or power figures appear here, because none were measured on my own hardware. The number that matters is the one your box produces

Jellyfin ships point releases often, and 12.0 will move some of this. Read the official documentation alongside any guide, including this one.

Product links on this site are plain links. We earn nothing from them — see our disclosure policy.