Install Jellyfin Media Server on Ubuntu 20.04 LTS
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 other major 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.
In the following tutorial, you will learn how to install Jellyfin on Ubuntu 20.04 Focal Fossa, 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.
Prerequisites
- Recommended OS: Ubuntu 20.04.
- User account: A user account with sudo or root access.
- Internet Access
The tutorial will utilize the terminal interface, which can be found in the show applications menu.
Example:
Update Operating System
Update your Ubuntu 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@ubuntu ~]$ sudo whoami
root
To set up an existing or new sudo account, visit our tutorial on How to Add a User to Sudoers on Ubuntu.
Use the following command with the root password to log in to use the root account.
su
Install Dependecies:
You will need to make sure you have the following packages installed to successful install the Jellyfin Media server:
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 in Ubuntu 20.04’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 -
If imported correctly, you will get the following output in your terminal:
OK
Import the Repository
The next step is to import the repository:
echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu focal main" | sudo 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:
TYPE Y, then press the 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:
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
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.
Select your Preferred display language and click on the Next -> button to proceed.
Next, you will come across creating a username and password.
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.
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:
Choose your Language, then click on the Next -> button.
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.
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.
Now you will be in your dashboard.
If you set up media during the installation, it will automatically appear.
Reset Initial Setup
If you made an error during the initial setup, 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.
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
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
Option 1 — 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:
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
Option 2 — 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:
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.
Updating Jellyfin Media Server
Jellyfin can be updated per the standard apt update & apt upgrade commands 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
Removing (Uninstall) Jellyfin Media Server
To remove Jellyfin from your Ubuntu 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 Ubuntu 20.04 and setting up permissions and remote access through Apache or Nginx.
Overall, the media server is quite an exciting project. 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.