How to Install Jellyfin Media Server on Debian 11

Jellyfin is a free, open-source multimedia application designed to organize, manage, and share digital media files to networked devices on an internal network and can be accessed remotely desired. It is a cross-platform and alternative to such other significant players, Plex and Emby. You can access it from a range of devices such as Mobile, Tablets, TV, and PCs or popular media devices like Roku or Nvidia shield. Jellyfin also serves media to DLNA and Chromecast-enabled devices and can fetch metadata just like Plex and Emby do so that you can organize your media into categories in a rich multimedia experience.

If you would like to test, Jellyfin has created a demo server to log in and check it out for yourself.

How to Install Jellyfin Media Server on Debian 11

In the following tutorial, you will learn how to install Jellyfin on Debian 11 Bullseye, along with how to set your media drives to have correct read and write access, plus if you want to stream an Apache or Nginx reverse proxy option remotely with how to secure it with Let’s Encrypt Free SSL certificate for both web applications.

Advertisement

Prerequisites

Update Operating System

Update your Debian operating system to make sure all existing packages are up to date:

sudo apt update && sudo apt upgrade -y

The tutorial will be using the sudo command and assuming you have sudo status.

To verify sudo status on your account:

sudo whoami

Example output showing sudo status:

[joshua@debian~]$ sudo whoami
root

To set up an existing or new sudo account, visit our tutorial on Adding a User to Sudoers on Debian.

To use the root account, use the following command with the root password to log in.

su

The tutorial will utilize the terminal for the installation found in Activities > Show Applications > Terminal.

Example:

How to Cinnamon Desktop Environment on Debian 11 Bullseye

Install Dependecies:

Before you proceed further with the tutorial, you will need to make sure you have the following packages installed:

sudo apt install apt-transport-https ca-certificates gnupg2 curl git -y

If you are unsure, just run the command; it will not harm you.

Install Jellyfin Media Server

Jellyfin does not come with Debian’s default repository, so you must import the Jellyfin GPG Key and repository.

Import GPG Key

First, you will need to import the GPG key to verify the authenticity of the package; without it, the installation will fail:

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

Import the Repository

The next step is to import the repository:

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

To finish off, update your repository listing to recognize the new additions as follows:

sudo apt update

Install Jellyfin

Now that you have the apt repository sorted, you can now proceed to install the Media server with the following command:

sudo apt install jellyfin

Example output with extra dependencies that will be installed:

How to Install Jellyfin Media Server on Debian 11

Type Y, then press enter key to complete installation.

Once installed, the Jellyfin service will be automatically started. To confirm this, use the following systemctl command:

systemctl status jellyfin

Example output:

How to Install Jellyfin Media Server on Debian 11

If your media server has not been started for some reason, use the following commands:

To start:

sudo systemctl start jellyfin

To enable on system boot:

sudo systemctl enable jellyfin
Advertisement

Jellyfin Media Server Initial Setup

To access the Jellyfin Web UI, you must open your Internet Browser and enter 127.0.0.1 on Jellyfin default port 8096.

Example below:

http://127.0.0.1:8096

You will come across the welcome screen for the initial server setup.

How to Install Jellyfin Media Server on Debian 11

Select your Preferred display language and click on the Next -> button to proceed.

Next, you will come across creating a username and password.

How to Install Jellyfin Media Server on Debian 11

Create a username and password; as stated in the above picture, more users can be entered once the initial setup is complete. Once done, click on the Next -> button to proceed.

Now you can set up your media libraries.

How to Install Jellyfin Media Server on Debian 11

Click on the big + (Plus sign) or Add Media Library button. From here, you can add your media folder, the setup is very straightforward, and users of Plex would especially feel a very close resemblance. Once done, click the Next -> button to proceed.

The next screen is the Metadata Langauge screen:

How to Install Jellyfin Media Server on Debian 11

Choose your Language, then click on the Next -> button.

How to Install Jellyfin Media Server on Debian 11

If you will be using or, in better words accessing the server from outside and or behind a proxy, make sure to set Allow remote connections to this server as is the default setting in this case. If you are only accessing a local network, disable this.

Now you will see the screen saying you have finished the installation.

How to Install Jellyfin Media Server on Debian 11

Easy step, click on the Finish button to finish.

You will be taken to the login screen to sign in with the user account and password you created in the initial setup.

How to Install Jellyfin Media Server on Debian 11

Now you will be in your dashboard.

How to Install Jellyfin Media Server on Debian 11

If you set up media during the installation, it will automatically appear.

Reset Initial Setup

If you made an error during the initial set up you could revert with the following steps:

Open the system.xml file:

sudo nano /etc/jellyfin/system.xml

Change the following, which is located on line 4:

<IsStartupWizardCompleted>true</IsStartupWizardCompleted>

To this:

<IsStartupWizardCompleted>false</IsStartupWizardCompleted>

Restart the Jellyfin server:

sudo systemctl restart jellyfin

Once you have reset the initial setup, revisit the HTTP://127.0.0.1:8096 and restart the process again.

Advertisement

Setup Permissions for Media Drives

Jellyfin will require to have read and execute permission on your media directories. You can use chown or chgrp commands; however, you will learn to use the setfacl command for the tutorial. This is being covered since it has the potential, later on, to be more secure, and you can control access at a very detailed level compared to the default way of chown and chgrp.

To install, run the following command:

sudo apt install acl -y

Debian should have this installed by default but run the command to be safe if unsure.

Now, you have a few options with the setfalc command, but realistically you won’t be going through giving each movie and tv show permissions; instead, the easier way is to use the recursive flag (-R) that will provide Jellyfin access it needs for everything located in the directory and subdirectories.

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

If you need to assign permission to individual media directories or files, use the following:

sudo setfacl -m u:jellyfin:rx /media/mymediadrive/example-name-of-file-or-directory

Setup Apache as a Reverse Proxy

You can set up a reverse proxy to access Jellyfin from a remote computer or network. In this example, the tutorial will set up an Apache proxy server. If you want to use Nginx, skip this part and go to the Setup Nginx as a Reverse Proxy.

First, install Apache:

sudo apt install apache2 -y

By default, Apache should be enabled if it is not activated. use:

sudo systemctl start apache2

To enable Apache to be started on boot, use the following command:

sudo systemctl enable apache2

Example output if successful:

Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable apache2

Verify the status of Apache:

sudo systemctl status apache2

Example output:

How to Install Jellyfin Media Server on Debian 11

To use Apache as a reverse proxy, you need to enable the module with the following command:

sudo a2enmod proxy proxy_http headers proxy_wstunnel

Next, create a virtual host for your subdomain:

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

You will need an active domain name which can be purchased for as little as 1 to 2 dollars if you do not have one. NameCheap has the best cheap domains going around and if you prefer a .com, use Cloudflare.

After you have created your sub-domain, add the following to the server block file:

<VirtualHost *:80>
    ServerName jellyfin.example.com

    # Comment to prevent HTTP to HTTPS redirect
    Redirect permanent / https://DOMAIN_NAME

    ErrorLog /var/log/apache2/DOMAIN_NAME-error.log
    CustomLog /var/log/apache2/DOMAIN_NAME-access.log combined
</VirtualHost>

# If you are not using a SSL certificate, replace the 'redirect'
# line above with all lines below starting with 'Proxy'
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName DOMAIN_NAME
    # This folder exists just for certbot(You may have to create it, chown and chmod it to give apache permission to read it)
    DocumentRoot /var/www/html/jellyfin/public_html

    ProxyPreserveHost On

    # Letsencrypt's certbot will place a file in this folder when updating/verifying certs
    # This line will tell apache to not to use the proxy for this folder.
    ProxyPass "/.well-known/" "!"

    ProxyPass "/socket" "ws://SERVER_IP_ADDRESS:8096/socket"
    ProxyPassReverse "/socket" "ws://SERVER_IP_ADDRESS:8096/socket"

    ProxyPass "/" "http://SERVER_IP_ADDRESS:8096/"
    ProxyPassReverse "/" "http://SERVER_IP_ADDRESS:8096/"

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem
    Protocols h2 http/1.1

    # Enable only strong encryption ciphers and prefer versions with Forward Secrecy
    SSLCipherSuite HIGH:RC4-SHA:AES128-SHA:!aNULL:!MD5
    SSLHonorCipherOrder on

    # Disable insecure SSL and TLS versions
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

    ErrorLog /var/log/apache2/DOMAIN_NAME-error.log
    CustomLog /var/log/apache2/DOMAIN_NAME-access.log combined
</VirtualHost>
</IfModule>

Save the file (CTRL+O), then exit (CTRL+X).

Now do a dry run to make sure no errors in the Apache configuration or your virtual host:

sudo apache2ctl configtest

If everything is working correctly, example output should be:

Syntax OK

Enable the virtual host on Apache as follows:

sudo a2ensite jellyfin.conf

Then restart Apache:

sudo systemctl restart apache2

Setup Nginx as a Reverse Proxy

You can set up a reverse proxy to access Jellyfin from a remote computer or network. In this example, the tutorial will set up an Nginx proxy server.

First, install Nginx:

sudo apt install nginx -y

By default, Nginx should be enabled if it is not activated. use:

sudo systemctl start nginx

To enable Nginx to be started on boot, use the following command:

sudo systemctl enable nginx

Example output if successful:

Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable nginx

Verify the status of Nginx:

sudo systemctl status nginx

Example output:

How to Install Jellyfin Media Server on Debian 11

If you would like to install the latest Nginx build, see our tutorial on How to Install Latest Nginx Mainline or Stable on Debian 11.

Now, create a new server block as follows:

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

You will need an active domain name which can be purchased for as little as 1 to 2 dollars if you do not have one. NameCheap has the best cheap domains going around and if you prefer a .com, use Cloudflare.

After you have created your sub-domain, add the following to the server block file:

server {
      listen 80;
      server_name jellyfin.example.com;

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

    set $jellyfin jellyfin;
    resolver 127.0.0.1 valid=30;

    # 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";

    location = / {
        return 302 https://$host/web/;
    }

    location / {
        # Proxy main Jellyfin traffic
        proxy_pass http://$jellyfin: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://$jellyfin:8096/socket;
        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;
    }
}

Save the file (CTRL+O), then exit (CTRL+X).

Now do a dry run to make sure no errors in the Nginx configuration or your server block:

sudo nginx -t

If everything is working correctly, example output should be:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx for the change to take effect:

sudo systemctl reload nginx

If you have set up your domain and DNS records to point to your server IP, you can now access your Jellyfin Media Server at jellyfin.example.com.

Secure Nginx or Apache with Let’s Encrypt SSL Free Certificate

Ideally, you would want to run your Apache or Nginx on HTTPS using an SSL certificate. The best way to do this is to use Let’s Encrypt, a free, automated, and open certificate authority run by the nonprofit Internet Security Research Group (ISRG).

First, install the certbot package as follows:

Apache:

sudo apt install python3-certbot-apache -y

Nginx:

sudo apt install python3-certbot-nginx -y

Once installed, run the following command to start the creation of your certificate:

Apache:

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

Nginx:

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

This ideal setup includes force HTTPS 301 redirects, a Strict-Transport-Security header, and OCSP Stapling. Just make sure to adjust the e-mail and domain name to your requirements.

Now your URL will be https://jellyfin.example.com instead of HTTP://jellyfin.example.com.

If you use the old HTTP URL, it will automatically redirect to HTTPS.

How to Update Jellyfin Media Server

Jellyfin can be updated as per the normal apt update command that you would use most of your time upgrading packages on your system.

To check for updates:

sudo apt update

If one is available, use the upgrade command:

sudo apt upgrade

How to Remove (Uninstall) Jellyfin Media Server

To remove Jellyfin from your Debian system. First, remove the software using the following command.

sudo autoremove install jellyfin --purge -y

Next, remove the added repository if you have no plans to use Jellyfin again.

sudo rm /etc/apt/sources.list.d/jellyfin.list

And that is it; you have successfully deleted Jellyfin from your system.

Comments and Conclusion

The tutorial has covered quite a bit of installing Jellyfin on Debian 11 Bullseye and setting up permissions and remote access through Apache or Nginx.

Overall, the media server is quite an exciting project, and it is immaculate and pleasant on the eyes and works well out of the box. If you are a long-term Plex or Emby user, it is a good idea to keep an eye n this as an alternative if you are not willing to swap now as this could be a valuable savior.

Subscribe
Notify of
5 Comments
Inline Feedbacks
View all comments
Alvaro
Guest
Thursday, January 6, 2022 8:44 am

Hello. The first thing to congratulate you on the great manual you have made. I have not had problems at any point and everything is very well explained. But I have a problem with the syncplay function since it does not work through https but it does work if I access with my local ip. Could you give me a hand?

Alvaro
Guest
Reply to  Joshua James
Friday, January 7, 2022 6:57 am

Thank you very much for the quick response.
I am using nginx
Thank you

Alvaro
Guest
Saturday, January 8, 2022 9:41 pm

Hello.
I can now create the groups in syncplay. Just add this line: proxy_set_header Upgrade $ http_upgrade.
Thank you

adplus-dvertising
5
0
Would love your thoughts, please comment.x
()
x