Jellyfin is a free, open-source media server software that lets you stream your own movies, music, photos, and videos to any device from anywhere in the world. Unlike Plex or Emby (which are commercial services), Jellyfin offers true privacy: no mandatory accounts, no tracking, no ads, and you own your entire server. This guide covers installing Jellyfin on an Ubuntu 22.04 VPS, setting up an Nginx reverse proxy with HTTPS for secure remote access, adding media libraries, and implementing proper security controls for protecting personal content.
In short: Jellyfin is a free, open-source, privacy-respecting media server perfect for self-hosted streaming. This article covers installation on Ubuntu 22.04 VPS, configuring Nginx reverse proxy with Let's Encrypt HTTPS, adding media libraries, and securing remote access. Since most VPS lack GPU, transcoding relies on CPU cores—limit concurrent streams to 1-2 and reduce bitrate to avoid CPU overload.
What is Jellyfin and How Does It Differ from Plex?
Jellyfin is a media server application that centralizes your digital media collection—movies, TV shows, music, photos, podcasts, and even audiobooks—in one place, then streams them to smartphones, computers, smart TVs, tablets, and other devices across your network or over the internet.
The key difference from Plex: Jellyfin is truly open-source and free. There are no mandatory accounts tied to a company, no usage tracking, no advertisements, and you retain complete control over your server. Plex is a commercial service that may require a subscription and tracks your viewing habits. Emby is also a commercial product. Jellyfin is community-driven with no commercial incentives, making it ideal for privacy-conscious users and self-hosting enthusiasts.
Why Host Jellyfin on a VPS?
- Privacy: Your movies and music never pass through someone else's servers. Everything stays on your own VPS under your full control.
- No Subscription Fees: Unlike Plex (which charges for some features) or paid plans, Jellyfin is completely free.
- Complete Control: You decide who gets access, when, and your VPS is yours to manage with root privileges.
- Global Accessibility: Host on any VPS anywhere in the world—Thailand, Singapore, or beyond—and stream from any location.
- Remote Access via HTTPS: With a proper domain and SSL certificate, stream 4K content securely from anywhere.
Prerequisites and System Requirements
To run Jellyfin effectively, you need:
- Ubuntu 22.04 LTS VPS: With root or sudo access for administration.
- SSD Storage: At least 500 GB (ideally 1–2 TB depending on media library size). Avoid slow HDD storage.
- Multi-core CPU: Minimum 2 cores; 4+ cores recommended (since most VPS lack GPU, transcoding is CPU-dependent).
- RAM: 2–4 GB minimum for comfortable operation.
- Bandwidth: At least 10 Mbps; VPS providers like AsiaGB using SSD can handle this easily.
- Domain Name: For secure HTTPS remote access (e.g., media.example.com).
| Specification | Minimum | Recommended |
|---|---|---|
| CPU Cores | 2 | 4 or more |
| RAM | 2 GB | 4 GB |
| SSD Storage | 500 GB | 1–2 TB |
| Bandwidth | 10 Mbps | 50 Mbps or higher |
| OS | Ubuntu 22.04 LTS | Ubuntu 22.04 LTS |
Installing Jellyfin on Ubuntu 22.04
Follow these steps to install Jellyfin from the official Ubuntu repository with automatic updates.
Step 1: Update System Packages
Before installing, update the package list and upgrade existing packages:
sudo apt update sudo apt upgrade -y
Step 2: Add Official Jellyfin Repository
Jellyfin maintains an official Ubuntu repository, ensuring you receive security updates automatically:
sudo apt install curl gnupg2 -y curl https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - echo "deb https://repo.jellyfin.org/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/jellyfin.list sudo apt update
Step 3: Install Jellyfin
Now install Jellyfin and its systemd service:
sudo apt install jellyfin -y
Step 4: Start Jellyfin Service
Enable Jellyfin to start automatically on reboot and start it now:
sudo systemctl enable jellyfin sudo systemctl start jellyfin
Check status:
sudo systemctl status jellyfin
Look for "active (running)"—if you see this, Jellyfin started successfully.
Jellyfin Initial Web Setup
Once Jellyfin is running, open a web browser on your client device and navigate to:
http://your-vps-ip:8096
Replace "your-vps-ip" with your actual VPS IP address (e.g., 192.0.2.123) or localhost if accessing from the VPS itself.
You'll see the Jellyfin server setup wizard. Complete these steps:
- Select Language: Choose English or your preferred language.
- Create Admin Account: Set a username and password for the administrator. Use a strong password with uppercase, lowercase, numbers, and symbols.
- Configure Location: Select country and currency settings.
- Add Media Libraries: Jellyfin will ask if you want to add media now. You can skip this—we'll add libraries in the next section.
Tip: Save your admin password securely. This credential grants full access to your personal music and movie library.
Adding Media Libraries
You now need to create folders on your VPS to store media files and tell Jellyfin where they are.
Step 1: Create Media Folders on Your VPS
SSH into your VPS and create the media directory structure:
sudo mkdir -p /mnt/media/{movies,tv,music,photos}
sudo chown -R jellyfin:jellyfin /mnt/media
sudo chmod -R 755 /mnt/media
This creates /mnt/media/movies, /mnt/media/tv, /mnt/media/music, and /mnt/media/photos, all owned by the jellyfin user.
Step 2: Add Libraries in Jellyfin Web UI
Back in the Jellyfin web interface, click "Libraries" in the sidebar.
- Click "Add Library"
- Select media type: Movies, TV Shows, Music, Photos, etc.
- Click "Next"
- Set folder path: /mnt/media/movies (for movies), /mnt/media/tv (for TV shows), etc.
- Click "Add"
Jellyfin automatically scans the folder and fetches metadata (title, year, poster, ratings) from online databases.
Tip: Organize video files in subfolders by title, e.g., /mnt/media/movies/The-Matrix/ or /mnt/media/tv/Breaking-Bad/Season-1/. Jellyfin uses folder and file names to look up metadata. For example, "The.Matrix.1999.1080p.x264.mkv" will match correctly on TMDB.
Transcoding Considerations on VPS
Transcoding converts video from one format to another or reduces quality (e.g., 4K to 1080p) to lower bandwidth usage. Most VPS lack GPU, so transcoding is CPU-intensive and can slow your server.
Challenges with VPS Transcoding
- CPU-Intensive: A 4K video may require 80–100% CPU to transcode in real-time.
- Concurrent Streams: A 4-core VPS can handle 1–2 transcoded streams simultaneously, not 10.
- Bitrate: 4K video may need 15–25 Mbps, which your VPS may struggle to handle.
Solutions
- Limit Concurrent Streams: In Admin > Policies > Maximum concurrent streams, set a limit (e.g., 2).
- Reduce Remote Bitrate: Ask users to select "Remote" in the Jellyfin app and choose lower bitrate (1–5 Mbps instead of 8–20 Mbps).
- Pre-transcode Media: If resources allow, pre-transcode videos before playback (time-consuming but removes real-time CPU load).
- Disable Hardware Acceleration: If your VPS has no GPU, leave hardware acceleration off.
Warning: Do not set transcoding bitrate too high. If a user tries to stream 4K and your VPS transcodes it to 1080p at 10 Mbps, the CPU may spike and the server may become unresponsive.
Setting Up Nginx Reverse Proxy with HTTPS
Jellyfin listens on localhost:8096 by default. For secure remote access, set up an Nginx reverse proxy in front with HTTPS.
Step 1: Install Nginx and Certbot
Install Nginx and certbot for managing Let's Encrypt certificates:
sudo apt install nginx certbot python3-certbot-nginx -y
Step 2: Create Nginx Configuration
Create the Nginx configuration file for Jellyfin:
sudo nano /etc/nginx/sites-available/jellyfin
Paste the following configuration (replace media.example.com with your actual domain):
server {
listen 80;
server_name media.example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name media.example.com;
ssl_certificate /etc/letsencrypt/live/media.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/media.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 20M;
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_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
}
}
Press Ctrl+X, then Y to save.
Step 3: Enable the Nginx Site
Create a symbolic link and test the configuration:
sudo ln -s /etc/nginx/sites-available/jellyfin /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
The nginx -t command checks syntax. If you see "syntax is ok," you're good.
Step 4: Obtain Let's Encrypt Certificate
Use certbot to get a free HTTPS certificate:
sudo certbot certonly --nginx -d media.example.com
Answer certbot's prompts (email, agree to ToS, etc.). Your certificate is now stored at /etc/letsencrypt/live/media.example.com/
Step 5: Configure Jellyfin for HTTPS
In the Jellyfin web UI, go to Admin > Networking:
- Set "Public HTTPS Port" to 443
- Set "HTTPS Certificate Path" to /etc/letsencrypt/live/media.example.com/fullchain.pem
- Set "HTTPS Key Path" to /etc/letsencrypt/live/media.example.com/privkey.pem
- Save
Jellyfin is now accessible at https://media.example.com with secure HTTPS.
Warning: Do not change Jellyfin's default port (8096). Nginx routes port 80 and 443 to the internal Jellyfin server on 8096 automatically.
Security for Remote Access
Since you're streaming personal content over HTTPS, implement proper security measures.
Prevent Unauthorized Access
- Strong Passwords: Use long passwords with uppercase, lowercase, numbers, and symbols. Example: MyJelly9@2024!Secure
- Disable Public Registration: Go to Admin > Policies > Allow user registration and set to Off so strangers can't create accounts.
- Manually Manage Users: Create user accounts yourself and share credentials securely.
- Monitor Access: Visit Admin > Logs periodically to see who accessed your server and when.
Optional: Add VPN Protection
For extra privacy, restrict Jellyfin access to VPN users only (requires running a VPN server like WireGuard or OpenVPN on your VPS). This prevents direct internet exposure but adds setup complexity.
Security Tip: Cloudflare Tunnel (free) is another option: create an encrypted tunnel from your VPS to Cloudflare, then access Jellyfin through a Cloudflare domain. This avoids opening any ports on your VPS except SSH.
Firewall Configuration with UFW
Protect your VPS by allowing only necessary ports:
Enable UFW and Configure Rules
sudo ufw enable sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp
If you want LAN access to Jellyfin directly (bypassing Nginx), add:
sudo ufw allow 8096/tcp
However, if using Nginx reverse proxy (recommended), port 8096 doesn't need to be exposed to the internet.
Check Firewall Status
sudo ufw status
Ports 22, 80, and 443 should show as ALLOW.
Summary
You've successfully installed Jellyfin on an Ubuntu VPS, configured an Nginx reverse proxy with HTTPS, added media libraries, and secured remote access. Your private media server is now ready to stream your movie and music collection to any device worldwide.
Key Takeaways:
- Most VPS lack GPU, so CPU-based transcoding is limited—restrict concurrent streams and bitrate.
- Always use HTTPS with valid certificates and strong passwords.
- Disable public registration and manage users manually.
- Consider VPN or Cloudflare Tunnel for additional security layers.
- Monitor access logs periodically for suspicious activity.
Frequently Asked Questions
How is Jellyfin different from Plex?
Jellyfin is free, open-source, and truly private—no mandatory accounts, tracking, or ads. Plex is a commercial service that may require subscriptions and tracks your viewing habits. Emby is also commercial. Jellyfin is community-driven with zero commercial interests.
How do I add movies to Jellyfin?
Create a /mnt/media/movies folder on your VPS, copy video files (.mkv, .mp4, etc.) into it, then in Jellyfin's web UI go to Libraries > Add Library > Movies, set path to /mnt/media/movies, and save. Jellyfin automatically scans and fetches metadata.
How does transcoding work on a VPS without a GPU?
VPS uses CPU-based (software) transcoding, which is very resource-intensive. Limit concurrent streams to 1-2, ask users to select lower bitrate (1-5 Mbps instead of 8-20 Mbps), and avoid 4K streams to prevent CPU overload.
How do I secure Jellyfin on the internet?
Use HTTPS with a valid certificate (Let's Encrypt), set a strong password, disable public registration, manually create user accounts, check logs regularly, and consider VPN or Cloudflare Tunnel for extra security.
Start Your AsiaGB VPS Today
AsiaGB VPS runs on SSD storage across every plan, with Thailand or Singapore datacenter options and full root access from day one — starting at 500 THB/month (Linux), backed by a Thai support team.
See VPS Plans