How to Install Jellyfin Media Server on Debian 10 Buster

This tutorial will be showing you how to install Jellyfin media server on Debian 10 server/desktop. Jellyfin is a free, open-source application that allows you to organize your movies, TV shows, music and photos in one beautiful interface and stream those media files on your PC, tablet, phone, TV, Roku, etc on the network or over the Internet. Jellyfin can be installed on Linux, MacOS and Windows.

Install Jellyfin Media Server on debian 10 buster

Jellyfin Features

Jellyfin is a fork from the Emby media server. It packs a lot of the same features as Plex and Emby.

  • Unlike Plex or Emby, Jellyfin is 100% free and open-source. No ads. No playback limit on mobile apps.
  • Watch Live TV and set automatic recordings to expand your library.
  • Automatically fetch artwork, metadata from TheTVDB, TheMovieDB, The OpenMovie Database and Rotten Tomatoes.
  • Supports DLNA.
  • Optional plugins can be installed to provide additional features.
  • Supports hardware acceleration of video encoding/decoding using FFMpeg.
  • And more.

Install Jellyfin Media Server on Debian 10

Jellyfin isn’t included in the default Debian repository, but it has its own repository. Run the following command to add Jellyfin repository to your Debian 10 system.

echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian buster main" | sudo tee /etc/apt/sources.list.d/jellyfin.list

Next, run the following command to import the Jeffyfin GPG key to Debian system so that APT can verify package integrity during installation.

wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add -

And because this repository uses HTTPS connection, we also need to install apt-transport-https and ca-certificates package.

sudo apt install apt-transport-https ca-certificates

Finally, update the package index on your Debian system and install Jellyfin.

sudo apt update

sudo apt install jellyfin

This command will also install 3 other packages as dependencies:

  • jellyfin-ffmpeg: for video transcoding.
  • jellyfin-server: the back end server.
  • jellyfin-web: the front end web interface.

Now Jellyfin media server is installed, we can check its status with:

systemctl status jellyfin

As you can see, it’s running on my Debian 10 system. (Press q key to take back control of the terminal.)

debian-10-server-jellyfin-guide

If Jellyfin media server isn’t running, you can start it with:

sudo systemctl start jellyfin

Jellyfin Media Server Initial Setup

The web-based management interface is available at port 8096. You can access Jellyfin web interface via the following URL.

http://127.0.0.1:8096/web

If you installed Jellyfin on a remote Debian server, you need to set up a reverse proxy with Nginx or Apache in order to access the web UI, which is explained later in this tutorial.

The first step is to choose your preferred language.

install-jellyfin-media-server-debian-10

On the next screen, create a user account.

jellyfin-debian-10-apt-repository

Now you can add libraries. Click Add Media Library button.

jellyfin-debian-buster-server

Select a content type (movies, music, tv shows, etc) and display name.

Then click the Plus (+) button to select a folder of the content.

jellyfin media folder path

Note that the jellyfin user needs to have read and execute permission on your media directories. For example, my 2T external hard drive is mounted under /media/linuxbabe/ , which is owned by root. Users not in group root can’t access it, so I run the following command to give user jellyfin read and execute permission. (I do not recommend changing ownership with chown or chgrp command. Using the setfacl command will suffice.)

sudo setfacl -m u:jellyfin:rx /media/linuxbabe/

You may also need to assign permission on individual media directories like below.

sudo setfacl -m u:jellyfin:rx /media/linuxbabe/directory-name

It can be tempting to add the recursive flag (-R), which gives jellyfin read and execute permission on every file and sub-directory on the drive.

sudo setfacl -R -m u:jellyfin:rx /media/linuxbabe/

If your external hard drive is only used for storing media files, then you can do so, but if you have sensitive files on the external hard drive, don’t do it.

Once you finish adding your media folders, you can configure the library settings. Choose your language, country, etc.

jellyfin library settings

Click Ok and Next button. You can always add more libraries later. The next step allows you to choose if remote access will be enabled. I don’t recommend enabling the native remote access method, because it doesn’t provide HTTPS encryption, so untick both checkboxes. If you need remote access, please read how to set up reverse proxy later in this article.

jellyfin remote access

Click Next and Finish button. Finally, log into your Jellyfin account.

Redo the Initial Setup

If you made a mistake in the initial setup, you can start it over. First, edit the Jellyfin configuration file.

sudo nano /etc/jellyfin/system.xml

Change

<IsStartupWizardCompleted>true</IsStartupWizardCompleted>

to

<IsStartupWizardCompleted>false</IsStartupWizardCompleted>

Save and close the file. Then restart Jellyfin.

sudo systemctl restart jellyfin

Now visit localhost:8096/web and you will see the setup wizard again.

Where to Download Movie and TV Shows

  1. Use a Torrenting client like Deluge.
  2. Learn how to download from Usenet.

Advantages of Usenet

  1. It gives you better privacy because others can’t see what you are downloading.
  2. Superfast download speed.
  3. Files are usually kept much longer then torrent files. For example, Newsdemon stores files for 4430 days (more than 12 years), so you can download old content at a very fast speed.

Setting Up Reverse Proxy

Since it listens on 127.0.0.1:8096, Jellyfin Web interface is only available to connections from the same computer. To be able to access the Jellyfin Web interface from a remote computer, we can set up a reverse proxy for Jellyfin with Nginx or Apache.

Nginx

Nginx is a very populuar web server and reverse proxy. If you prefer to use Nginx, run the following command to install it.

sudo apt install nginx

Then create a server block file for Jellyfin.

sudo nano /etc/nginx/conf.d/jellyfin.conf

Add the following content to this file. Replace jellyfin.example.com with your own domain name. You should also add a DNS A record for this sub-domain. If you don’t have a real domain name, I recommend going to NameCheap to buy one. The price is low and they give whois privacy protection free for life.

server {
      listen 80;
      listen [::]:80;
      server_name jellyfin.example.com;

      access_log /var/log/nginx/jellyfin.access;
      error_log /var/log/nginx/jellyfin.error;

      set $jellyfin 127.0.0.1;

      location / {
          proxy_pass http://127.0.0.1:8096;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;

          # Disable buffering when the nginx proxy gets very resource heavy upon streaming
          proxy_buffering off;
      }

      # location block for /web - This is purely for aesthetics so /web/#!/ works instead of having to go to /web/index.html/#!/
      location ~ ^/web/$ {
          # Proxy main Jellyfin traffic
          proxy_pass http://$jellyfin:8096/web/index.html/;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;
      }

      location /socket {
          # Proxy Jellyfin Websockets traffic
          proxy_pass http://$127.0.0.1:8096;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;
      }

        # Security / XSS Mitigation Headers
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Content-Type-Options "nosniff";
}

Save and close this file. Then test Nginx configuration.

sudo nginx -t

If the test is successful, reload Nginx for the change to take effect.

sudo systemctl reload nginx

Now you can access Jellyfin media server via jellyfin.example.com.

Apache

If you prefer Apache over Nginx, then install Apache web server by using the following command.

sudo apt install apache2

To use Apache as a reverse proxy, we need to enable the proxy modules and the header module.

sudo a2enmod proxy proxy_http headers proxy_wstunnel

Then create a virtual host file for Jellyfin.

sudo nano /etc/apache2/sites-available/jellyfin.conf

Put the following configurations into the file. Replace jellyfin.example.com with your actual domain name. Don’t forget to create DNS A record for this sub-domain. If you don’t have a real domain name, I recommend going to NameCheap to buy one. The price is low and they give whois privacy protection free for life.

<VirtualHost *:80>
   ServerName jellyfin.example.com
   ErrorDocument 404 /404.html

   #HTTP proxy
   ProxyPass / http://localhost:8096/
   ProxyPassReverse / http://localhost:8096/

   #Websocket proxy
   SSLProxyEngine on
   <Location /:/websockets/notifications>
        ProxyPass wss://localhost:8096/:/websockets/notifications
        ProxyPassReverse wss://localhost:8096/:/websockets/notifications
   </Location>

   Header always unset X-Frame-Options
</VirtualHost>

Save and close the file. Then enable this virtual host.

sudo a2ensite jellyfin.conf

Restart Apache

sudo systemctl restart apache2

Now you can access Jellyfin media server using the domain name jellyfin.example.com.

Enable HTTPS

To encrypt the HTTP traffic when you visit Jellyfin server from outside, we can enable HTTPS by installing a free TLS certificate issued from Let’s Encrypt. Run the following command to install Let’s Encrypt client (certbot) on Debian 10.

sudo apt install certbot

If you use Nginx, then you also need to install the Certbot Nginx plugin.

sudo apt install python3-certbot-nginx

Next, run the following command to obtain and install TLS certificate.

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d jellyfin.example.com

If you use Apache, then you need to install the Certbot Apache plugin.

sudo apt install python3-certbot-apache

Next, run the following command to obtain and install TLS certificate.

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d jellyfin.example.com

Where:

  • --nginx: Use the nginx plugin.
  • --apache: Use the Apache plugin.
  • --agree-tos: Agree to terms of service.
  • --redirect: Force HTTPS by 301 redirect.
  • --hsts: Add the Strict-Transport-Security header to every HTTP response. Forcing browser to always use TLS for the domain. Defends against SSL/TLS Stripping.
  • --staple-ocsp: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS.

The certificate should now be obtained and automatically installed.

jellyfin-enable-https-certbot-letsencrypt-debian

And you can access Jellyfin web interface via HTTPS: https://jellyfin.example.com.

How to Upgrade Jellyfin on Debian 10

When a new version of Jellyfin media server comes out, you can upgrade it by executing the following commands.

sudo apt update

sudo apt upgrade

Then restart Jellyfin.

sudo systemctl restart jellyfin

Troubleshooting

If your Debian server runs WireGuard VPN, you might see the following error in Jellyfin log (sudo journalctl -eu jellyfin).

[ERR] Error sending socket message from 10.0.0.102 to 239.255.255.250:1900
System.Net.Sockets.SocketException (0xFFFFFFFF): Bad value for ai_flags

This error means that the message can’t be sent from your WireGuard interface to the 239.255.255.250, which is the SSDP (Simple Service Discovery Protocol) multicast address. This is due to that your WireGuard interface is not allowed to reach the IP address.

To solve this problem, edit your WireGuard interface configuration file.

sudo nano /etc/wireguard/your-interface.conf

Find the AllowedIPs parameter. Mine is like below.

AllowedIPs = 10.0.0.0/8

As you can see, the VPN client is allowed to connect to the 10.0.0.0/8 network only. Now add the 239.255.255.250 address.

AllowedIPs = 10.0.0.0/8, 239.255.255.250

Save and close the file. Restart WireGuard.

sudo systemctl restart wg-quick@your-interface

Restart Jellyfin.

sudo systemctl restart jellyfin

Check the Jellyfin log (sudo journalctl -eu jellyfin) again. The above error should be gone.

Wrapping Up

I hope this tutorial helped you install Jellyfin media server on Debian 10. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 1 Average: 5]

One Response to “How to Install Jellyfin Media Server on Debian 10 Buster

  • Hello Xiao,

    Thanks for the write-up on this. Complete, clear and concise as usual… I am in the process of switching from plex to Jellyfin and this will be most helpful. It is good to see Jellyfin getting attention as a good open source option.

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.


The maximum upload file size: 2 MB.
You can upload: image.