Configuring Jellyfin Media Server

In this post, I documented how I configured Jellyfin media server on my home server. Having Jellyfin media server up and running, I and all family members living in the same house can connect to the home network and watch movies stored on the media server. Not only that, by establishing a secure SSH tunnel from my home server to my VPS in the cloud, now I can watch movies from my media server from anywhere in the world.

Why Creating a Media Server?

Before delving into details, I should explain the reason why I created a home media server. Because currently, consuming media is just a click away from subscribing to various streaming services such as Netflix oar Disney+ Hot Star. By subscribing to these services, we can watch movies right away, without having to think about creating the infrastructure to support a home media server.

The first reason is proficiency in the area, meaning I technically understand what are needed to establish a home media server. I know how to setup a network; I know how to run a low energy server which must run 24×7; and I know there are free of charge software that we can use to establish a media server such as Jellyfin, Emby, and Plex. Without knowing them all, it is rather difficult to start the journey of establishing a media server for our home.

Second reason is I want to have freedom of choice when watching movies or TV series. You know, not all movies we like are available from a streaming service. If want to watch all movies we like, we could end up subscribing all the streaming services available, and you know how much money is needed to subscribe all those streaming services. This worsened by the fact that if we stop subscribing from a particular streaming service, we won’t be able to watch all the movies that we already watched previously from that particular streaming service.

The third reason is organizing the movies and TV series we already owned into a library that is connected to the various movie online meta data. Just by providing the title of the movie as the file name, all related meta data information such as synopsis, movie thumbnail, actors and actresses, ratings, etc. are automatically fetched from the online meta data provider.

How to Configure Jellyfin Media Server as a Docker Container

Now I’m going to explain step by step how to configure Jellyfin Media Server as a Docker Container. The first prerequisite of this process is having the required hardware. The second prerequisite is proficiency in the basic Docker concept. The third prerequisite is having all the movies converted from DVDs or blue ray disks into media files. And the fourth prerequisite is the knowledge to establish a secure tunnel to Access Jellyfin media server from the internet.

1. Preparing the Hardware

The home media server needs a hardware to run 24×7. This can be served any computer we have such as a PC or a laptop. The requirement to run it continuously 24×7 demands that the hardware is both durable and energy efficient. Most PC should be durable enough to run 24×7, but most of them require a high amount of energy to run. A used laptop that has a good cooling fan should be durable enough, and it should consume less energy than a desktop PC.

Other important requirement is the capability to provide hardware acceleration for transcoding movies. This usually requires a CPU that has a specific feature such as Intel Quick Sync. However, if your PC or laptop has a GPU, it usually capable to perform transcoding since most GPU should be able to do this.

My choice for the hardware is an Orange Pi 5. It is an SBC (single board computer) that is certainly more energy efficient than a desktop PC. Under heaviest load, it should only consume maximum energy of 20 watts. It is powered by a quad core ARM CPU RK 3588 with ARM Mali-G610 GPU. It should be capable of hardware accelerated video processing for both encoding and decoding, although at the time of writing the driver support is somewhat limited. It even has 6 Tops AI computing power that should be capable for the object detection function used in Frigate NVR.

Other part of hardware that is also important is the disk for storing the movie files. The disk size should be big enough to store a lot of movies, and it should be fast enough especially for read access. However, if we don’t have many devices connected, a regular HDD should be enough. I use a 4TB regular external HDD to store all my movie files attached to the Orange Pi 5 via one of its USB 3 ports.

2. Creating the Jellyfin Docker Container

I assume you already understand how to create a Docker Container using Docker compose file. If not, you can read my previous post on how to prepare an Orange Pi 5 for a Home Server as an example of using an SBC as a host of Docker Containers using Armbian operating system.

The following code snippet is the docker-compose.yml file for my Jellyfin Docker Container.

YAML
version: "3"

services:
  jellyfin:
    container_name: jellyfin
    image: linuxserver/jellyfin:latest
    #ports:
    #  - 8096:8096
    #  - 8920:8920
    #  - 7359:7359/udp
    #  - 1900:1900/udp
    volumes:
      - /opt/jellyfin/config:/config
      - /opt/jellyfin/cache:/cache
      - /mnt/data/media:/media:ro
    network_mode: host
    restart: unless-stopped

Note that I commented out the ports section because I use host network mode. If you use default network mode (bridge), you should open the comment to specify port mapping.

The media storage is mapped to /mnt/data/media. This is the external disk connected to the Orange Pi 5 SBC via a USB 3.0 port. Because this is an external drive, it is not automatically mounted each time the host server is restarted. We have to add an entry to the /etc/fstab file to automatically mount an external disk.

To map an external disk, we have to know the UUID of the device. First, list all external disks connected to the server by typing the following command in a Terminal window.

Zsh
lsblk

If we have only one external disk connected, we should see something like /dev/sda1 in the result. To inquiry the UUID of the disk, type the following command in a Terminal window.

Zsh
sudo blkid /dev/sda1

Now we should see the UUID and the type of the disk in the result. Put the UUID and the type in the /mnt/fstab file. Specify the mount point, for example /mnt/data. The following code snippet shows my /etc/fstab file after adding the new entry on line 6 and 7.

Plaintext
# <file system>                           <mount point>  <type>  <options>   <dump>  <fsck>
UUID=AE4F-9A42                            /boot/firmware vfat    defaults    0       2
UUID=514446b0-d237-4aa9-b842-4a16a8737626 /              ext4    defaults    0       1
/swapfile                                 none           swap    sw          0       0

# External disks
UUID=72359EA637E8327E                     /mnt/data     ntfs    defaults     0       0

Restart the server. Then open a Terminal window and now we should be able to cd into the /mnt/data directory.

3. Preparing the Movie Files

The movie files should be organized into a specific directory, let’s call it media. We can organize them further based on their types: movies and TV shows. We can make two directories for both of them: movies directory to store all movies and shows directory to store all TV shows.

Each movie should be contained in a sub directory under movies directory. For example, I created a sub directory called Avatar (2009) to store all files related to the Avatar movie. Then I put the Avatar (2009) [1080p].mp4 and Avatar (2009) [2160p].mp4 files into this sub directory along with all the subtitle files (if any). Here is the content of the directory displaying using tree command.

Follow the guidance of naming movie file from the Jellyfin movies naming convention page. At least we put the year of the movie as part of the filename. If we have multiple resolutions for the movie, we can put resolution marker as the part of the filename. For example: 720p for HD, 1080p for full HD, and 2160p for 4K. Having multiple resolutions of the movie can free up the server resources from performing transcoding, especially if our server doesn’t have hardware acceleration feature.

4. Establishing a Secure Tunnel to Access Jellyfin Media Server from the Internet

We don’t have to perform this step if we just intend to watch our movies from inside our house. Otherwise, we have to prepare the infrastructure required to access our home server from the internet. There are some methods to achieve this goal. The one that I am using is establishing a secure tunnel to a VPS that I already have. Using this method, we use the public IP of the VPS and also the public domain pointing to the IP as the URL of the Jellyfin website that we exposed to the internet. There is no direct connection from the internet to our home server.

I already explained the details of this method in my previous post. Although my explanation in the post is for establishing a secure tunnel for Home Assistant, but the same method can be used to establish a secure tunnel for Jellyfin.

The most important thing when we expose the Jellyfin media server from the internet is the upload bandwidth of our internet connection. Because when we watch a movie from the internet, from our side as the viewer, we “download” the movie. But, from the server side (our home network), the movie is “uploaded” to the internet. So, please make sure that we have adequate upload bandwidth to watch the movie smoothly.

Conclusion

In this post, I have documented why I created a home media server compared to subscribing to various streaming services. I also explained step by step how to configure a home Jellyfin media server as a Docker Container using docker compose file. Lastly, I also mentioned how we can expose our Jellyfin media server to the internet by establishing a secure tunnel to a VPS that I already owned.

Agus Suhanto M.T.I., PMP®

Leave a Comment

Your email address will not be published. Required fields are marked *