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.
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.
Hi EP,
Let’s troubleshoot your Nginx error step by step:
1. Test your config syntax
Fix any reported issues (
missing semicolons,mismatched braces,wrong file paths).2. Check for port conflicts
Ensure nothing else is listening on port
80(Apache might be running already).3. Enable your Jellyfin proxy file
(Or use your distro’s preferred
sites-enabledpath.)4. Restart Nginx
If it still fails, please post the exact output of these two commands:
That information will pinpoint the root cause. If Nginx continues to be challenging, remember the article also includes Apache setup instructions as an alternative.