Getting Started with TrueNAS Scale | Part 3 | Installing Jellyfin via the GUI + Apps Explainer

Introduction

Welcome to Part Three!
This builds on the first two parts of this Series, which you can find here and here.

Having installed TrueNAS Scale and created a Storage Pool and Dataset, we’re now ready to install an application on the Host.

This Guide will go over the general options and then show you step-by-step how to install a Docker Container via the GUI, at the example of Jellyfin.

Learning about Docker Containers on TrueNAS Scale

Before we start to configure anything, it’s important to understand what we’re working with.

TrueNAS Scale is built on k3s, which is a leightweight implementation of Kubernetes - a Container Orchestration Solution focused on making it easy to deploy Containers on multiple Devices in a Cluster for Load Balancing or High Availability.

These functions aren’t yet implemented fully in TrueNAS Scale and we won’t be covering much about Kubernetes, but it is important to keep in mind that there’s more than just plain Docker behind the GUI.

TrueNAS Scale natively provides two ways to run Containers:

Deploying Containers by using pre-made Helm Charts (Official, TrueCharts)

A Helm Chart defines how Kubernetes deploys Containers and related resources like Networking and Storage.

TrueNAS Scale’s Official Apps and also the community-maintained TrueCharts Catalogue are a collection of Helm Charts, which pre-configure almost everything and make it very easy to deploy more complex applicatons that might need multiple Microservices, e.g. a Webserver, Database and Application Container.

I’ll not go over how to deploy these kinds of Apps in this Guide as it’s quite well-documented, but here are some resources that might come in handy if you choose that path:

TrueCharts Manual
TrueNAS Scale Official App Documentation
Using App Catalogues in TrueNAS Scale

Deploying Custom Containers via the “Launch Docker” GUI

As an alternative methods to using pre-configured Helm Charts, TrueNAS Scale has an Option to launch Containers via a GUI which exposes most important Configuration Options.

It makes it easy to deploy Containers without much knowledge of the underlying Kubernetes while still exposing enough Options to make more advanced configuraitons feasible.

It is the only sanctioned Option you will have if the App wanted is not in the TrueCharts Catalogue, installing via the CLI is almost always a bad idea as it will break on Host Updates.

This is also what we’ll be using in the example below to install Jellyfin on our TrueNAS Scale Server.

About Jellyfin

image

Jellyfin is an Application that can be an equivalent to Netflix, Spotify and a Kindle Library by creating your own local streaming service.

It’s strength include:

  • Very good metadata system - not much manual labor is involved in organizing your media library in comparison to e.g. Navidrome
  • Multi-User Support, including watch-together and finegrained permissions
  • Clients for many Platforms, which can remote-control each other (example: phone as remote for kodi client)
  • Support for lots of codecs, transcoding support with GPUs

A few links that might come in helpful:
Clients for Jellyfin
Hardware-Acceleration (Out of this Guide’s Scope)
Organizing Media

Preparations

  • Log Onto your TrueNAS Scale Server

  • Click on “Apps” in the Side Menu:
    Screenshot from 2022-03-30 20-13-38

  • Select the Pool in which TrueNAS will Store Application Data, if you have a Pool Made up of SSDs, that one is preferable:
    Screenshot from 2022-03-30 20-14-18

Now we’re being greeted by the Apps Section, displaying available Official Applications:

If we were going to install Applications only via that Method, we’d be done now, but since we’ll use the “Launch Docker” GUI, there’s two more Steps ahead:

Creating a Dataset for Peristent Jellyfin (or other Containers) Storage

To make sure Configuration Data of our Jellyfin Container isn’t lost if we upgrade or uninstall the App, we’ll store its data in a separate Dataset in our Pool.

Changing the Permissions on the Dataset

Create Directories for Jellyfin in the Newly Created Dataset

  • Navigate to System Settings → Shell:
    Screenshot from 2022-03-30 20-39-46

  • Enter the Following Commands into the Shell, one by one:

cd /mnt/tank/appdata
mkdir jellyfin
cd jellyfin
mkdir config
mkdir cache
ls
  • The Output after you’re done should look like this:
    Screenshot from 2022-03-30 20-46-15

Configuring Jellyfin

Now that we’ve created a Dataset with Directories that Jellyfin can use to store Configuraton Data Persistently, we’re ready to Configure Jellyfin.

Configuring Networking to the Container

We have Multiple Choices Now, only follow one of the two Folders below as mixing the settings up will Collide:

Add an External Interace, for Example an IP on a Network Bridge which VMs can also make use of or an IP Alias on a NIC
  • 1 Click “Add” next to "Configure External Interfaces

  • 2 Choose an Interface, it can be a Bridge or a Physical NIC

  • 3 Select to Choose a Static IP

  • 4 Select an IP Alias for the Interface which is on your Subnet

  • Now Click "Next Two Times, the "Port Forwarding Section can be Skipped:
    Screenshot from 2022-03-30 20-55-08

Forward a Port to the Host's IP, this means Jellyfin has to stay on a Port over 9000

After you’ve followed one of the two Options above, Continue on with the Guide.

Configuring Storage for Jellyfin

Now, we’ll have to create two Host Path Volumes for Config and Cache, plus one to access our Dataset where Media is Stored.

As this is a lot to Type out (and possibly get wrong), here’s everything Entered:

# Host Path 1:
/mnt/tank/appdata/jellyfin/config
/config
# Host Path 2:
/mnt/tank/appdata/jellyfin/cache
/cache
# Host Path 3:
/mnt/tank/media
/media
-> Check Read Only!

Finishing Up!

  • Click “Next” two more times:
    Screenshot from 2022-03-30 20-55-08

  • Change the Upgrade Policy to “Kill existing Pods before creating new ones” and click next another two times:

  • You’ve now configured Jellyfin, all that’s left is to click “Save” to confirm your settings:
    Screenshot from 2022-03-30 21-27-29

  • Wait for the Container to Download and Deploy:
    Screenshot from 2022-03-30 21-28-33
    Screenshot from 2022-03-30 21-29-35

First Steps after Installation

CONGRATUALATIONS! You’ve now successfully installed and deployed Jellyfin.

Navigate to the Web Interface one of the following ways:

This Section will be extended more to cover changing Ports and Libraries more indepth

Conclusion

Now that you’ve successfully set up Jellyfin on your TrueNAS Scale Server, it’s time to get some Popcorn and start watching movies!

In the next Part of the Guides we’ll go about setting up File Shares via the Network.

22 Likes

Part 1: Getting Started with TrueNAS Scale | Part 1 | Hardware, Installation and Initial Configuration

Part 2: Getting Started with TrueNAS Scale | Part 2 | Learning ZFS Storage in TrueNAS; Creating a Pool, Dataset and Snapshot Task

3 Likes

Thank you for this! I have my collection in place now. Initially I thought it would get from the truecharts app repo but it seems to have got it from ix-charts? If TrueNAS had these in the first place, why wont they show it along with the built-in Apps? This will break when TrueNAS updates, isnt it?

1 Like

You got the Container itself from Docker Hub, I’ll edit the Wiki to explain it a bit more.

If you followed the Guide it shouldn’t break on updates, unless if there’s major breaking changes introduced in the Updates.

But even if it should break - with the config stored in a dataset, you don’t loose any data

1 Like

I should add that proper folder name and filename structures are required because Jellyfin parses the directory structure so that it could be run with nice pictures, description, cast, etc that it pulls from the internet. I didnt RTFM and just dumped my video collection in the media dataset and did not recognize a lot of my movies and tv series.

https://jellyfin.org/docs/general/server/media/movies.html

2 Likes

Thanks for your tutorials. I am planning to upgrade (or rather replace) my current TrueNAS core with TrueNAS scale. And jellyfin sounds like it might be good choice for my occasional movie/show watching. Maybe combined with something that can automatically download torrents. And I see that Jellyfin is written in .net core which is nice, the new multiplatform opensource version of .net is very cool and performant…

2 Likes

Hi, I’m runing into a problem witht the networking part, I’d like to be able to reach Jellyfin witht he IP of the host i.e: SERVERIP:8096 but i’m not sure how to achieve this?

1 Like

It’s explained in this Part of the Guide: Click me!

There is two Options there, you’ve got to follow the Tutorial in the Second Spoiler and forward a Port to the Host’s IP.

Keep in mind it has to be a port higher than 9000 on the Host Side.

If there’s any additional questions, let me know.

2 Likes

Thank you for the speedy response, I’m now scanning librabry

2 Likes

Thank you for the guide. Can you go through how to ensure hardware encoding with a GPU via Docker? I’m going to do my own research as well, but if you see this, I’d love a published answer :slight_smile:

1 Like

I’m able to add the Host Path mount points but Jellyfin is not able to show the contents of the libraries. Is there additional permission required on the dataset?

1 Like

Welcome to the Forum!

The Dataset which has your Media needs to have Read Permissions enabled and the Dataset used for Jellyfins App Data should be owned by the “apps” user and group as described above.

From what you’re saying it seems the issue is with accessing the Media Dataset from the Jellyfin Container?

To be able to help you better, please share your Datasets Permissions and Jellyfin Docker Configuration with us. It’s hard to diagnose a problem otherwise.

Hello,

I have followed this guide without an issue until creating the Jellyfin directories within the dataset. My datasets aren’t visible in the shell, and I haven’t been able to successfully troubleshoot this. I can use the cd command to navigate to /mnt/[POOL NAME]/ no problem, but none of my datasets appear as a directory within this directory. I can use the TAB command when I’m inside /[POOL NAME]/ to see directories like boot/, conf/, data/, root/, etc, but no dataset names. And I did create the appdata dataset according to the guide, with the mount point path displaying as /mnt/[POOL NAME]/appdata under Storage > View Permissions. Everything looks mounted normally and running fine when I use “zfs list”. When I use the “ls” command when I’m inside /mnt/[POOL NAME]/ it only returns “ix-applications”. Any help much appreciated.

1 Like

Hi, welcome to the Forum.

Could you please run the following commands in the shell:

zfs get mountpoint [POOLNAME]/[DATASETNAME]
zfs mount -l

This should tell us where the Dataset is supposed to be mounted and whether it actually is.

Please also make sure that the Parent Dataset to your “appdata” Dataset isn’t read-only - I’ve seen that preventing the mounting of child datasets before.

2 Likes

Good looking guide.
Just to vent some frustrations/warnings about Jellyfin. It’s storage management is absolute garbage. If you install IPTV and let it run it will just fill the drive with data. Always. It has no garbage collection. No cleanup. Nothing. And no option to create it properly. It continues to download and save the video stream until the window is closed or the system crashes.
And it does the same thing with every other stream to a degree where it will have access to a file, and create a million part files, in the file system on disk, for each open stream, and only remove them when the stream ends. It scales like trash and operates very poorly.

Just created an account to ask the following: how does the Jellyfin configuration change when you set up the container from the truecharts repository? The configuration steps when you install from a repository is pretty different than when you setup from scratch like you did here.

1 Like

TrueCharts makes a preconfigured Helmchart for the underlying Kubernetes and only exposes certain settings.
In this Tutorial we pull the Docker Image directly and then a Helm Chart gets created with the options specified in the “Launch Docker” Dialogue.

I prefer getting the Imagine directly from Docker Hub, because you cut out the Middle Main (TrueCharts).

But if you want to use the TrueCharts App, you can set up the Storage the same way as described here and won’t have to worry too much about the rest.

Sorry for the basic question…
Issue: TrueNAS is working great, installed pihole ‘app’ but unable to identify the IP I should be using to setup DNS across my devices

I was previously using proxmox and hosting pihole in a vm, and this is my first time trying out containers. I’ve been enjoying FreeNAS and the convenience of just deploying apps/containers without the extra upkeep of maintaining VMs sounds great… but my inexperience is not letting me actually USE the app.

I’ve tried:

  1. Googling: most of the searches point to docker setup commands that set the IP when running it from a host machine, so not the case here.
  2. Running

ip a

from the shell of the app: got a nat-ish address that isn’t in my networks range, and couldn’t use it to resolve even the admin web portal so that’s clearly not working
3. Using the FreeNAS server’s IP address: didn’t work

Sorry for such basic question

1 Like

Did you install PiHole from the official Charts (under the “Available Applications” Tab)?

Or did you install it via “Launch Docker” manually, or TrueCharts…

This is most likely just a matter of networking - you’d either pass through a Port from the Hosts IP Address or create a Network Bridge on the Host and add PiHole to that, if you want to use more standard Ports.

I can’t give you any more specific help without knowing how you set it up - it’d be very helpful to see some screenshots of your configuration.

@felixthecat I installed directly from the “available applications”. I agree with the networking part.

It prompted me to choose web, dns tcp and dns udp ports, which I set accordingly. DHCP and host network are disabled.

I’m unclear how to passthrough a port from the host’s IP, given that the clients only have an IP field for their DNS servers.

Could I just use the host’s IP by just checking the ‘Enable Host Network’?