Arnan de Gans

The international goose

How to set up a Ubuntu Media server with Jellyfin, Samba, Qbittorrent and video conversion scripts

As I have written over the past few months. I've been working on building an Ubuntu Media Server. This machine runs Samba Filesharing, sFTP, Jellyfin server, Qbittorent, and a basic Apache webserver. It also handles video and audio conversion to a uniform super compatible format. Should you want to import all your DVDs and CDs into your Jellyfin Library.

I've been using this setup for a while now, and this is the, for me, fine tuned version of how to install Ubuntu server from a blank OS to a fully working Media Server.

For these steps to work we assume that you have a freshly installed Ubuntu Server 24 LTS (or newer) on a Intel PC of some sort. I use a refurbished HP Elitedesk computer, but any kind of PC will (should) work.

Hardware used

Basic Ubuntu setup

I've used the standard installation for everything and mounted the 6TB Nas drive on /data. This is relevant for the installation below. If you mount your storage disk elsewhere, change the commands below accordingly.
Once the installation of Ubuntu completes and you're at the login prompt you can continue with the steps below.

The server can use DHCP, but I always prefer a static IP. Set that up according to your network.

For networking, we use .home.lan as a network domain. You can use your own domain if you prefer. Or if you do not have a local domain or DNS server, you can use .local or rely on IP Addresses. In this setup, the Media server will be at media.local.lan or media.local.
I always prefer to use DNS names for convenience.

A few ground rules

For the commands below, most of them can be copy/pasted. But take note of what you're doing! A few require you to make some changes. Such as enter a hostname, your username(s), time zone and things like that. Never blindly copy anything! Always, always interpret and try to understand what you're doing!

Commands that need your input are easily identified by all capital words.
YOURUSERNAME always refers to your own user other than root! The other 'usernames' are other users of your choosing.

I've ignored the UFW firewall entirely, this computer only works on my LAN network and sits behind a pfSense firewall. The UFW firewall is installed on Ubuntu Server by default, rules can easily be added to it. Make sure you let Samba, Apache, sFTP and Jellyfin through it if you decide to use it. Also a few ports for Qbittorrent are probably useful to have.
You can set up and use the firewall, but setting it up is beyond the scope of this article.

After installing Ubuntu

Here we set the servers hostname, I use 'media' for mine. Set your timezone too.

sudo hostnamectl set-hostname media
sudo timedatectl set-timezone UTC

Next run all updates.

sudo apt update
sudo apt upgrade

Scripts and extra files

This zip-file contains scripts and configuration files referenced throughout this guide.

Download: arnan.me_ubuntu-server-files.zip
File: zip file / Size: 1.3 MB / Uploaded: September 08 2026

Install software and users

This command will install almost all required software which we will set up in this guide.

sudo apt install acl avahi-daemon avahi-utils samba intel-media-va-driver-non-free intel-opencl-icd vainfo qbittorrent-nox apache2 libapache2-mod-cgi vsftpd -y

Set up your users. If you're also installing qbittorrent, you'll need the qbtuser. The rest is optional. Switch out USERNAME with the desired username. Add as many as you need.

sudo adduser qbtuser
sudo adduser USERNAME

Set up folders

Here we set up all the required folders. User groups, user permissions and ownership. As you'll note we don't really touch the base Ubuntu file system. Everything of note goes on the /data mount.

The second line adds folders for video files; movies, tv-shows and animation. Add different ones as needed. If you don't care for an Animated library you can leave that out. Or if you want a different storage routine - Sort by genre for example - add different folders. These are what the various Jellyfin libraries will look for once you create them.

sudo mkdir -p /data/{jellyfin-data,downloads,incomplete,converted,www,scripts}
sudo mkdir -p /data/jellyfin-data/{movies,tv-shows,animation}
sudo mkdir -p /data/jellyfin-data/{cache,meta}
sudo mkdir -p /data/scripts/log
sudo mkdir -p /data/www/cgi-bin

sudo groupadd media-server
sudo usermod -aG media-server YOURUSERNAME
sudo usermod -aG media-server www-data
sudo usermod -aG media-server qbtuser
sudo usermod -aG media-server ftp
sudo usermod -aG users YOURUSERNAME
sudo usermod -aG users YOUROTHERUSERS

sudo chown root:media-server /data
sudo chown -R YOURUSERNAME:media-server /data/jellyfin-data /data/downloads /data/incomplete /data/converted /data/scripts
sudo chown -R www-data:media-server /data/www

sudo setfacl -R -m g:media-server:rwx /data/jellyfin-data /data/downloads /data/incomplete /data/converted
sudo setfacl -R -d -m g:media-server:rwx /data/jellyfin-data /data/downloads /data/incomplete /data/converted

I found that the best way to give multiple users and groups access to folders was to use ACLs. Basic chown/chmod didn't quite cut it and I got hopelessly stuck with it after several days of messing with it.

With that out of the way we continue to configure the various services the server is going to offer. Each is optional, especially the Torrent client. But I find all of them useful.

Set up the sFTP server

sFTP can be used for reliable remote file management. You'll need a sFTP client like Cyberduck or Transmit to access it. Sometimes sending/downloading larger files will go more consistent compared to Samba shares.

Configure the sFTP server

See config file in zip-file -> /configurations/vsftpd/
Copy the file to /etc/vsftpd.conf (or write a new one based on it).

You can tune this file to your needs of-course. I just use this (mostly default) version which lets me browse and handle folders and files as needed. Which is all I want from sFTP.

Make vsftpd start on boot

sudo systemctl enable vsftpd
sudo systemctl start vsftpd

Avahi (mDNS/Zeroconf/Bonjour)

Avahi handles auto-discovery for mDNS. Mac users will know this service as Bonjour. Windows and Linux users may know this as Zeroconf or simply mDNS. This takes away the direct need for a local DNS resolver and allows you to use basic domain names on your network. The primary use-case here is to make Samba visible on the network.

Add services

See services file in zip-file ->/configurations/avahi/
Move all .service files to /etc/avahi/services with sFTP, or a generic location and move them with ssh/terminal later.

These enable auto-discovery services for Samba, the Webserver (Apache) and JellyFin.
The Samba service is the most important one. We rely on Avahi to promote Samba since Samba's own method (netbios/multicast) kinda sucks.

Make avahi start on boot

sudo systemctl enable avahi-daemon
sudo systemctl start avahi-daemon

Check it out

If you're curious what Avahi outputs to the network you can check what it does with this command.

avahi-browse -at

It should list all services, so you should see terms like; jellyfin and smb.

Samba

Samba handles filesharing between computers. Most notably, this mounts folders of the server as external drives on a MacOS, Linux and Windows computer. The purpose of Samba in this set up is to give access to the Downloads, Converted and Jellyfin folders. But you're of-course free to add more (or less) shares in smb.conf.

Add users

Add as many users as you need. These users need to exist as Ubuntu users also. So create those first.

sudo smbpasswd -a USERNAME

Configuring Samba

See configuration file in zip-file ->/configurations/samba/
Move the file to /etc/samba/smb.conf with sFTP, or a generic location and move it with ssh/terminal later.

This configuration is highly optimized for fast and reliable file transfers. It demands modern(ish) Operating Systems using the latest SMB3 protocol. Any computer of the last 10 years should be able to connect.

Test the configuration

Test the configuration. This'll warn about the socket options, since we override their defaults and auto-tuning.

testparm
sudo smbstatus

Make samba start on boot

sudo systemctl enable smbd
sudo systemctl start smbd

JellyFin

The actual media server. JellyFin comes from it's own repository. So to install it we need to get it from a different server then everything else.

Installing Jellyfin

From ~ (home) run the following.

curl -s https://repo.jellyfin.org/install-debuntu.sh -O

Then to install the package.

sudo bash install-debuntu.sh

Add the JellyFin user to groups

Jellyfin requires its own user, and that user needs access to certain folders and services. We gave the media-server group access already at the start, so adding Jellyfin to that is the easiest without breaking other users access. The render group is for video conversion and hardware acceleration.

sudo usermod -aG render jellyfin
sudo usermod -aG media-server jellyfin

Make jellyfin start on boot

sudo systemctl enable jellyfin
sudo systemctl start jellyfin

Continue in your web browser

That's the basic installation done. Now you can configure the server through the browser.
Visit: http://media.home.lan:8096 in a web browser and do the basic setup from there.
Set the main folder to /data/jellyfin-data.

JellyFin Configuration

We set up folders for certain things at the start. You can configure those in Jellyfin.

Check Intel hardware encoding

If you're using an Intel CPU/GPU you can probably use hardware encoding. This works very efficient versus CPU encoding.

ls -l /dev/dri

Look for 'renderD128'. If it's there, all good. Skip the next header.

If renderD128 is not there

If it's not enabled, set up the users and permissions first.

sudo groupadd render
sudo usermod -aG render,video jellyfin
sudo usermod -aG render,video YOURUSERNAME
sudo usermod -aG render,video www-data

Then continue with the setup

Now we look for the Hardware Video Acceleration.

sudo -u jellyfin vainfo

If there are no errors, skip the next header.

If it says "error: failed to initialize"

If vainfo gave you an error. Install the drivers so Hardware encoding will work.

echo "LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri" | sudo tee -a /etc/environment
source /etc/environment

Enable hardware acceleration in Jellyfin

In Jellyfin (either via the Web GUI or the Jellyfin App), go to the admin dashboard. In the dashboard settings navigate to: Playback > Transcoding and select Intel Quicksync (QSV)

This depends a bit on the CPU, for my CPU I can use all codecs except:

Newer CPUs might support more or other codecs. You can check this in the Intel documentation, or ask Google Gemini / Duck AI for what your CPU supports.

Add Jellyfin users

If you won't be the only JellyFin user, add the ones you need. Family, friends, neighbors. Whoever you trust with it.
For the few people that have access to my server I've disabled: Live TV, Downloads, Transcoding and set a limit on remote streaming (via internet).
But do whatever makes sense for you.

I've disabled transcoding because we'll set up conversion scripts to convert every video to a compatible format so that your server will never have to transcode anything. I believe that transcoding files over and over is a waste of energy and CPU cycles. Better to do it right the first time. If you throw your files in without conversion you may need to enable transcoding for your users though.

QBittorrent

You can source your video and audio files from the internet if you so desire. Qbittorrent is a decent, and very popular, client to do that. Torrenting is not always legal, keep that in mind.

Setup

Do the basic setup as qbtuser, and exit when done.

sudo su qbtuser
qbittorrent-nox
exit

The actual configuration is done through a web interface.

Make qbittorrent start on boot

sudo systemctl enable qbittorrent
sudo systemctl start qbittorrent

Continue in your web browser

With the basic setup done. You can configure qbittorrent through the browser.
Visit: http://media.home.lan:8080 in a browser and do the basic setup from there.

Qbittorrent Configuration

Don't forget, we set up folders for certain things at the start. You'll use those in Qbittorrent.

Own the log

chown qbtuser:media-server /data/scripts/log/qbittorrent.log
chmod 664 /data/scripts/log/qbittorrent.log

This has Qbittorrent own the file, but the 'media-server' group can also see the file. Your user is in this group, letting you review the file if you need it.

Apache

And lastly we're setting up a simple webserver. This is so you'll have some basic monitoring scripts and a webpage to start file conversions from. This makes things more convenient and easy.

See configuration file in zip-file ->/configurations/apache/
Move the config file to /etc/apache2/sites-available/000-default.conf with sFTP, or a generic location and move it with ssh/terminal later.

This configuration file adds a vhost to apache (for your webpage) and looks for those files in /data/www/. It also sets the hostname to media.home.lan.

Add Apache modules

We'll need mod_rewrite and mod_cgi. These are like plugins (modules) for Apache. Everything else can be default.

sudo a2enmod rewrite cgi

Set up the website

See website files in zip-file ->/www/
Move the website files to /data/www/ with sFTP.

Once in place give the files the right permissions.

sudo chown YOURUSERNAME:www-data /data/www/*.*
sudo chown YOURUSERNAME:www-data /data/www/cgi-bin/*.sh
sudo chmod 0755 /data/www/cgi-bin/*.sh

Set up scripts

There are a couple of scripts that the webpages control, these convert audio and video files with ffmpeg to compatible formats.

See scripts in zip-file ->/scripts/
Copy all scripts to /data/scripts/ with sFTP.

Make them executable for the owner and group.

sudo chmod 0775 /data/scripts/*.sh

Make apache start on boot

sudo systemctl enable apache2
sudo systemctl start apache2

Done!

Reboot the system and it should all work once the system comes back online!

sudo reboot now

Usage

Jellyfin

Access Jellyfin through the webbrowser at http://media.home.lan:8096.
Or, of-course, through any of the JellyFin apps - I kinda like Swiftfin or just the default app. But any of them will do.

Samba

In MacOS the Samba server should be visible through auto-discovery in Finder, just look for the Network section in the sidebar. The server should be called Media Server.
To connect, click it and log in with any of the samba users you've created.

From Windows and Linux, the server should be easily found in its file manager. Or if not, add a network share and use smb://media.home.lan to connect to it. If you don't use a domain, smb://media.local or the IP Address should work. Log in as directed and mount shares as needed.

SSH & sFTP Server

Point your terminal to ssh USERNAME@media.home.lan. Follow the prompts and log in.
For file sharing, connect your sFTP client to media.home.lan:22 and follow the login prompts.

I mainly use sFTP to move files around with a GUI instead of ssh, so that new content can easily be added to JellyFin.

Webserver

In your webbrowser visit http://media.home.lan or http://media.local. This'll show a blue page with a few buttons on it. Each circular button acts as a shortcut to a function. From here you can connect to the Jellyfin web client and Qbittorrent, but also the converstion scripts. These pages embed shell scripts. The embedded script on the video and audio conversion page monitor the conversion script that will run in the background as needed.
If nothing is being converted but new files are detected in the /data/downloads/ folder it'll offer to convert them. Click the button and it starts doing so.

While converting files, the button is hidden and a elapsed time and remaining files counter is shown. This status updates every few seconds until the process is complete. Depending on what you're doing this can take minutes, or several hours.

The actual conversion scripts will look for compatible video files of any kind and try to convert them into standardized MKV files. For audio, it takes any compatible file and converts them to M4A files.
Simply throw any (common) type of video or audio file in the /data/downloads folder and the script will detect it.

I've created these shell/bash scripts myself and made the more complex parts work with suggestions from Google Gemini and Duck AI. This was a lot of trial and error, but I think they work pretty good now.

What the video conversion script does

What the audio conversion script does

QBittorrent

You can access the torrent client through http://media.home.lan:8080. This UI lets you manage your torrent/magnet downloads.

Conclusion

And there you have it. A self serving handy machine you can hook up to your network and let any kind of device connect to it. Stream audio and video all over your house. Of-course you'll only stream your own home-videos - Right?

Have fun!

diy, server, tech, software, network

⬅ Previous post
PfSense, Vlans and Wifi shenanigans