How to Install Jellyfin Media Server on Ubuntu Linux

Jellyfin Media Server offers a free, open-source platform for organizing and streaming your movies, music, and more. Unlike Plex or other proprietary alternatives, Jellyfin has no subscription fees, tracking, or data collection. The platform streams across devices (desktop, mobile, smart TVs), supports extensive media formats without constant transcoding, and extends functionality through plugins for metadata, subtitles, and more.

This guide covers installing Jellyfin Media Server on Ubuntu, importing the official repository, configuring file permissions with ACL, and optionally securing remote access through reverse proxies and SSL certificates. You’ll learn the complete setup process from initial installation to a production-ready streaming server.

Import Jellyfin APT Repository on Ubuntu

Update Ubuntu Before Jellyfin Installation

Before proceeding with the installation, you should update your packages to keep your Ubuntu operating system smooth and secure. Additionally, this prevents compatibility issues when installing the Jellyfin Media Server. Use the command line interface (CLI), Ubuntu’s built-in terminal environment, and enter the following command to update Ubuntu:

sudo apt update && sudo apt upgrade -y

Running this command updates the package list and upgrades all installed packages to their latest versions. As a result, this prevents compatibility issues during the Jellyfin installation.

Install Initial Packages For Jellyfin Media Server


Once the system update completes, you must ensure you have installed all the necessary packages on your Ubuntu system. These packages ensure a successful installation and smooth server operation.

To install the necessary packages, execute the following command:

sudo apt install apt-transport-https ca-certificates curl gnupg -y

Import Jellyfin Media Server APT Repository

The default Ubuntu repository doesn’t include Jellyfin. Therefore, you must import the Jellyfin GPG Key and repository to install the software. Furthermore, this confirms the package’s authenticity and verifies no one has tampered with it. APT (Advanced Package Tool) uses these repositories to download and update software securely.

Import Jellyfin GPG Key

First, create the dedicated keyring directory (if needed) and import the GPG key with limited trust scope:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/jellyfin.gpg
sudo chmod 644 /etc/apt/keyrings/jellyfin.gpg

These commands download the Jellyfin signing key, store it in /etc/apt/keyrings/, and restrict its permissions. Ubuntu will reference this key only for the Jellyfin repository, preventing it from inadvertently trusting unrelated sources.

Import Jellyfin Repository

Next, choose between the stable and unstable Jellyfin repositories to import. Stick with one repository to avoid conflicts; the stable channel is best for production servers, while the unstable channel delivers the latest development builds for testing new features.

To import Jellyfin Media Server stable (recommended) for everyday use:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/jellyfin.gpg] https://repo.jellyfin.org/$(awk -F'=' '/^ID=/{ print $NF }' /etc/os-release) $(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list

Alternatively, import Jellyfin Media Server unstable (development) if you need preview builds. This command writes to a separate list file so you can switch channels later without manually editing the stable configuration:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/jellyfin.gpg] https://repo.jellyfin.org/$(awk -F'=' '/^ID=/{ print $NF }' /etc/os-release) $(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release) unstable" | sudo tee /etc/apt/sources.list.d/jellyfin-unstable.list

Following repository import, update your system’s repository listing to recognize the new additions:

sudo apt update

Updating the repository listing ensures Ubuntu recognizes the new repository and can retrieve packages from it. Once updated, you’re ready to install Jellyfin.

Complete the Installation of Jellyfin Media Server on Ubuntu

Now that you’ve imported the Jellyfin repository and GPG key, you can install Jellyfin Media Server on Ubuntu using the following command:

sudo apt install jellyfin

Once installation completes, Jellyfin automatically starts. Next, verify the service is running correctly with this status check:

systemctl status jellyfin

If the Jellyfin service hasn’t started, manually start it with this command:

sudo systemctl start jellyfin

Additionally, enable the service to start automatically during system boot:

sudo systemctl enable jellyfin

These commands ensure Jellyfin runs now and launches automatically on every system boot. As a result, your server remains accessible even after restarts.

Initial Setup for Jellyfin Media Server on Ubuntu

With Jellyfin installed and running, you can now access the Web UI. Open your internet browser and enter the IP address of your server, followed by the default port 8096. For instance, if you’re accessing the Jellyfin server on the same machine where it’s installed, use 127.0.0.1 as the IP address.

For example, you can enter the following address in your browser’s address bar:

Example below:

http://127.0.0.1:8096

Once you enter the given address, the welcome screen for the initial server setup appears. This screen outlines the essential steps to configure Jellyfin for the first time, guiding you through the setup process.

Select Your Preferred Language and Region

During your first-time setup, follow these steps to configure your Jellyfin server:

  • Choose Display Language: Select your preferred display language, then click the “Next ->” button to continue.
  • Create User Account: Set a username and password for administrative access. Choose a strong, unique password with uppercase and lowercase letters, numbers, and symbols. Click “Next ->” after setting up.
  • Add Media Libraries: Click the “+” or “Add Media Library” button to select media folders for movies, TV shows, or music. Click “Next ->” once added.
  • Set Metadata Language: Choose the language for media metadata to enrich your collection with details like cast and plot summaries. Proceed by clicking “Next ->”.
  • Configure Remote Access: Allow remote connections and enable automatic port mapping to access your media from outside your local network. Click “Next ->” to continue.
  • Finish Setup: Confirm setup completion and click “Finish” to reach the login screen. Sign in with your created credentials.

Create Your Administrator Account

Following language selection, create your username and password, then click the “Next ->” button. Notably, you can add more users after completing the initial setup.

Setting up your media libraries is a key part of the process when you install Jellyfin Media Server on Ubuntu. Jellyfin uses these libraries to organize and display your media. To get the most out of your installation, create separate libraries for movies, TV shows, and music.

Add Your Media Libraries

Following user creation, add media content to Jellyfin by clicking the “+” or “Add Media Library” button on the Jellyfin dashboard. This click brings you to the Media Library setup screen, where you can select your media folder.

Once you’ve added your media libraries, click the “Next ->” button. You’ll land on the Metadata Language screen, where you can pick the language for your media content’s metadata, enriching your collection with details like cast, plot summaries, and reviews.

The setup mirrors that of Plex, making it straightforward for those familiar with Plex. After clicking the “Add Media Library” button, select the type of media you want to add: movies, TV shows, or music.

Once you’ve set up your media libraries and chosen your metadata language, proceed to configuring remote access for your Jellyfin media server. Remote access lets you view media content from different locations or devices outside your local network. This capability is one of the many benefits of running Jellyfin on Ubuntu.

Enable Remote Access to Your Server

To enable remote access, allow remote connections to your Jellyfin media server and turn on automatic port mapping. Allowing remote connections lets you access your media from any location with internet connectivity. Meanwhile, automatic port mapping simplifies the process by opening the required ports for incoming traffic to your Jellyfin server.

After enabling remote access, you can proceed to the next step. The next screen confirms that you have finished the installation and that your Jellyfin media server is ready.

Complete Initial Configuration

Once you confirm that you have finished the installation process, click the “Finish” button to complete the setup. This action will take you to the login screen, where you can then sign in with the user account and password you created during the initial setup.

Access the Jellyfin Dashboard

To access the dashboard, enter your username and password to sign in to your Jellyfin media server, then click the “Sign in” button.

Troubleshoot: Reset the Initial Setup

This section can be skipped unless you have issues or need to reset the installation process. However, if you encounter problems during setup, follow the steps below.

During your Jellyfin media server’s initial setup, you can reset the setup process if you make an error or mistake. To accomplish this, simply modify the “IsStartupWizardCompleted” value in the system.xml file and restart the Jellyfin server.

First, open the system.xml file with a text editor:

sudo nano /etc/jellyfin/system.xml

Next, locate and modify the “IsStartupWizardCompleted” value to reset the wizard:

<IsStartupWizardCompleted>false</IsStartupWizardCompleted>

Following the modification, save the file (CTRL+O) and exit (CTRL+X). This change resets the initial setup process, allowing you to start again from the beginning.

Then, restart the Jellyfin server to apply the changes:

sudo systemctl restart jellyfin

Once the server restarts, simply visit http://127.0.0.1:8096 to restart the setup wizard from the beginning.

Configure Jellyfin Media Server Permissions For Media Drives

Following installation, the media server requires read and execute permissions for your media directories. Access Control Lists (ACLs) provide fine-grained permission management beyond traditional Unix file permissions. Consequently, they let you grant specific users access without changing ownership or group membership.

First, install the ACL package if it’s not already present:

sudo apt install acl -y

Following ACL installation, grant Jellyfin access to your media directory and all subdirectories using the recursive flag. For example, replace /path/to/your/media with your actual media directory path:

sudo setfacl -R -m u:jellyfin:rx /path/to/your/media

Alternatively, for individual files or directories, specify the exact path:

sudo setfacl -m u:jellyfin:rx /path/to/your/media/specific-file-or-folder

After setting permissions, verify they were applied correctly by checking the ACL entries. This confirmation ensures Jellyfin can access your media:

getfacl /path/to/your/media

The output should show user:jellyfin:r-x in the ACL entries, confirming Jellyfin has read and execute access to the specified path. With these permissions configured, Jellyfin can now access your media files.

Manage Remote Access, Security, and Maintenance

Configure Ubuntu Server SSH For Jellyfin Media Server

When you want to securely access your Jellyfin Media Server remotely without exposing it directly to the internet, set up an SSH tunnel. This approach is useful when you don’t have a domain name or reverse proxy configured, as SSH provides encrypted access through a secure tunnel.

First, ensure SSH is installed on your Ubuntu server. If you haven’t installed OpenSSH server yet, you can install it with the following command:

sudo apt install openssh-server -y

Following installation, verify the SSH service is running:

systemctl status ssh

From your local computer, establish an SSH tunnel to forward port 8096. Make sure to replace username with your Ubuntu username and server-ip-address with your server’s actual IP address:

ssh -L 8096:localhost:8096 username@server-ip-address

This command creates a secure tunnel that forwards port 8096 on your local machine to port 8096 on the remote server. As long as the SSH session remains active, you can access the Jellyfin Media Server using this link in your web browser:

http://localhost:8096/web/index.html#/wizardstart.html

The SSH tunnel directs your browser’s HTTP request through the encrypted connection to the remote server’s Jellyfin instance. Therefore, keep the SSH terminal window open while using Jellyfin; closing it terminates the tunnel and disconnects your access.

Configure UFW Firewall for Jellyfin Media Server on Ubuntu

The Ubuntu Firewall (UFW) manages firewall rules in Ubuntu. By default, Ubuntu leaves the firewall disabled, so you need to install it (if necessary), open required ports, and then enable protection without locking yourself out of SSH.

If UFW isn’t installed, add it with this command:

sudo apt install ufw -y

Before enabling the firewall, allow SSH plus the ports Jellyfin and your reverse proxy require. Adding the rules first prevents accidental disconnections on remote servers:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8096/tcp

Once the allow rules exist, enable UFW:

sudo ufw enable

These commands keep the Jellyfin web UI available on port 8096, let reverse proxies serve traffic over HTTP/HTTPS, ensure certbot can complete HTTP-01 challenges, and maintain SSH access for remote administration.

Setup Apache or Nginx as a Reverse Proxy For Jellyfin Media Server

You can set up a reverse proxy to access Jellyfin from a remote computer or network. Additionally, this method provides secure HTTPS access and simplifies domain-based routing.

Setup Apache as a Reverse Proxy For Jellyfin Media Server

First, set up Apache as a reverse proxy by installing the Apache web server:

sudo apt install apache2

Apache should be enabled by default. However, if it’s not running, start it with this command:

sudo systemctl start apache2

Enable Apache to start automatically on boot:

sudo systemctl enable apache2

Next, enable the necessary Apache modules for reverse proxy functionality. These modules handle proxy requests and WebSocket connections:

sudo a2enmod proxy proxy_http headers proxy_wstunnel

After enabling modules, create a new virtual host configuration file for Jellyfin using the following command. This file will define how Apache routes traffic to Jellyfin:

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

Before continuing, make sure your domain has an A (or AAAA) record such as jellyfin.example.com pointing to your server’s public IP address so Apache can serve requests for the hostname you define below.

Once you’ve created your subdomain, add the following HTTP-only virtual host. It proxies traffic to Jellyfin immediately, and Certbot will layer HTTPS on top of this configuration after you request the certificate:


    ServerName jellyfin.example.com

    ProxyPreserveHost On
    ProxyTimeout 3600
    TimeOut 3600

    # WebSocket proxy
    ProxyPass "/socket" "ws://127.0.0.1:8096/socket"
    ProxyPassReverse "/socket" "ws://127.0.0.1:8096/socket"

    # Main Jellyfin proxy
    ProxyPass "/" "http://127.0.0.1:8096/"
    ProxyPassReverse "/" "http://127.0.0.1:8096/"

    ErrorLog /var/log/apache2/jellyfin-error.log
    CustomLog /var/log/apache2/jellyfin-access.log combined

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

Before enabling the virtual host, you can check whether there are any errors in the Apache configuration or virtual host file by performing a “dry run” using the following command:

sudo apache2ctl configtest

A successful test returns “Syntax OK,” confirming the configuration has no errors. This validation step prevents Apache crashes during the reload process.

If the test passes, enable the virtual host:

sudo a2ensite jellyfin.conf

Enabling the site creates a symbolic link between sites-available and sites-enabled directories, allowing Apache to serve the configuration. Next, restart Apache to apply the changes:

sudo systemctl restart apache2

Apache reloads with the new virtual host settings, making your Jellyfin reverse proxy active over HTTP. Continue to the Let’s Encrypt section below to secure the site with HTTPS.

Setup Nginx as a Reverse Proxy For Jellyfin Media Server

Nginx, a popular, lightweight, high-performance web server, is an excellent reverse proxy for accessing your Jellyfin media server from remote computers or networks.

To install Nginx, use this command:

sudo apt install nginx

Nginx should be enabled by default. However, if it’s not running, start it with this command:

sudo systemctl start nginx

Enable Nginx to start automatically on boot:

sudo systemctl enable nginx

Verify Nginx is running correctly. This check confirms the service started successfully:

sudo systemctl status nginx

After confirming Nginx is active, create a new server block file for Jellyfin:

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

Configure the server block with the following directives. Each directive controls a specific aspect of how Nginx handles requests:

  • listen: Specifies the port and address for Nginx (port 80 in this example)
  • server_name: Your domain name (replace jellyfin.example.com)
  • access_log and error_log: Locations for log files
  • location: Handles different URL paths and request types
  • proxy_pass: Forwards requests to Jellyfin on port 8096

Here is an example server block configuration. Initially, this configuration only uses HTTP (port 80). After you create an SSL certificate with certbot, it will automatically add the HTTPS (port 443) configuration and redirect all HTTP traffic to HTTPS:

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

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

    # 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 / {
        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;
        proxy_buffering off;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    location = /web/ {
        proxy_pass http://127.0.0.1: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_pass http://127.0.0.1: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;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

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

Test the Nginx configuration for syntax errors before applying it:

sudo nginx -t

A successful test displays confirmation that the configuration file syntax is valid. Then, reload Nginx to activate the new configuration:

sudo systemctl reload nginx

With your domain and DNS records pointing to your server IP, you can now access Jellyfin at jellyfin.example.com. Nginx forwards requests to Jellyfin’s web interface, enabling remote access through your domain.

Create Let’s Encrypt SSL Free Certificate For Jellyfin Media Server

Securing your reverse proxy with an SSL certificate enables HTTPS connections, encrypting traffic between users and your Jellyfin server. In addition, Let’s Encrypt provides free SSL certificates that renew automatically.

Install the appropriate certbot package for your reverse proxy. For Apache:

sudo apt install python3-certbot-apache

For Nginx:

sudo apt install python3-certbot-nginx

Create an SSL certificate with certbot. The command includes options for automatic HTTPS redirects (–redirect), HTTP Strict Transport Security (–hsts), and OCSP Stapling (–staple-ocsp) for enhanced security. Make sure to replace YOUR-EMAIL@example.com and jellyfin.example.com with your actual email and domain:

For Apache:

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

For Nginx:

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

After certificate creation, your Jellyfin URL changes to https://jellyfin.example.com. Furthermore, Certbot automatically configures your web server to redirect HTTP requests to HTTPS.

Test the automatic renewal process with a dry run:

sudo certbot renew --dry-run

If the dry run succeeds, you can set up automatic renewal by creating a cron job. Open the crontab editor:

sudo crontab -e

Add this line at the end of the file to check for certificate renewals daily at midnight:

0 0 * * * /usr/bin/certbot renew --quiet

Save and exit the crontab editor. The cron job runs daily, automatically renewing certificates within 30 days of expiration. As a result, your SSL certificate stays valid without manual intervention.

Update Jellyfin Media Server

Updating Jellyfin Media Server is similar to updating any other package on your system. Specifically, you can use the standard apt commands.

To check for updates, run the following command:

sudo apt update

If there are any updates available, run the upgrade command:

sudo apt upgrade

Remove Jellyfin Media Server

If you no longer require Jellyfin, you can easily remove it from your system. Simply use the following command to remove the software:

sudo apt remove jellyfin --purge

Next, remove the Jellyfin repository from your system so you don’t accidentally reinstall it in the future. Delete whichever list file you originally added (the following commands safely remove both possibilities):

sudo rm -f /etc/apt/sources.list.d/jellyfin.list
sudo rm -f /etc/apt/sources.list.d/jellyfin-unstable.list

And that’s it. You have successfully removed Jellyfin from your system.

Jellyfin Resources and Community Support

Use the following official resources to deepen your Jellyfin knowledge and troubleshoot advanced scenarios:

  • Jellyfin Official Website: Visit the official Jellyfin website for information about the media server, its features, and download options.
  • Jellyfin Documentation: Access comprehensive documentation for detailed guides on installing, configuring, and using Jellyfin.
  • Jellyfin Forum: Join the Jellyfin community forum to discuss issues, share solutions, and get support from other users.
  • Jellyfin Demo: Explore the live demo of Jellyfin to see the interface and features in action.

Conclusion

Jellyfin delivers a powerful, open-source media streaming platform without subscription fees or privacy compromises. The installation process covers repository imports, file permissions with ACL, and optional remote access through reverse proxies and SSL certificates. Your Ubuntu server now runs a customizable media hub that streams across devices while maintaining full control over your library and data.

2 thoughts on “How to Install Jellyfin Media Server on Ubuntu Linux”

  1. I came to a complete dead end at the reverse proxy setup. Cannot get past this:

    eric@[xxxxx]:~$ sudo systemctl start nginx
    Job for nginx.service failed because the control process exited with error code.
    See “systemctl status nginx.service” and “journalctl -xeu nginx.service” for details.

    Reply
    • Hi EP,

      Let’s troubleshoot your Nginx error step by step:

      1. Test your config syntax

      sudo nginx -t

      Fix any reported issues (missing semicolons, mismatched braces, wrong file paths).

      2. Check for port conflicts

      sudo lsof -i :80

      Ensure nothing else is listening on port 80 (Apache might be running already).

      3. Enable your Jellyfin proxy file

      sudo ln -s /etc/nginx/conf.d/jellyfin.conf /etc/nginx/sites-enabled/jellyfin.conf

      (Or use your distro’s preferred sites-enabled path.)

      4. Restart Nginx

      sudo systemctl restart nginx

      If it still fails, please post the exact output of these two commands:

      sudo nginx -t
      sudo journalctl -xeu nginx.service

      That information will pinpoint the root cause. If Nginx continues to be challenging, remember the article also includes Apache setup instructions as an alternative.

      Reply

Leave a Comment