Jellyfin Media Server: Movies and Music on a Dedicated Server
Introduction
Set up your own Netflix-style library with Jellyfin on a ServerStadium dedicated server or VM. This guide covers a clean Ubuntu 24.04 install, creating media folders, enabling a secure HTTPS site with Nginx + Let’s Encrypt, and basic multi-user setup.
Prerequisites
- A ServerStadium dedicated server or VM running Ubuntu 24.04.
- SSH access with a sudo-capable user.
- A domain/subdomain (e.g.,
media.example.com
) pointing to your server’s public IP.
Step 1 — Install Jellyfin (Official Repo Script)
The official installer adds the repository and installs Jellyfin and its codecs.
sudo apt update && sudo apt -y install curl gnupg apt-transport-https ca-certificates
curl https://repo.jellyfin.org/install-debuntu.sh | sudo bash
# If needed, ensure installed:
sudo apt -y install jellyfin
sudo systemctl enable --now jellyfin
sudo systemctl status jellyfin --no-pager
Step 2 — Create Media Folders & Permissions
sudo mkdir -p /srv/media/{movies,tv,music}
# Jellyfin runs as the "jellyfin" user by default
sudo chown -R jellyfin:jellyfin /srv/media
If you mount additional disks (e.g., at /srv/media
), ensure ownership stays with jellyfin:jellyfin
or grant group read access as needed.
Step 3 — First-Run Wizard
- Temporarily open the local port to finish setup:
sudo ufw allow 8096/tcp
- Browse to
http://<server-ip>:8096
, create the admin account, and add libraries pointing to/srv/media/movies
,/srv/media/tv
,/srv/media/mus ic
. - In Dashboard → Networking, leave HTTP at
8096
. We’ll put HTTPS behind Nginx next.
Step 4 — Secure HTTPS with Nginx Reverse Proxy
We’ll proxy Jellyfin (localhost:8096) behind Nginx on media.example.com
with a free Let’s Encrypt certificate.
sudo apt -y install nginx certbot python3-certbot-nginx
# Create the proxy config
sudo tee /etc/nginx/sites-available/jellyfin >/dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name media.example.com;
return 301 https://$host$request_uri;
}
server {
# For Nginx 1.25+: enable HTTP/2 explicitly
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name media.example.com;
# Let’s Encrypt paths (created by certbot)
ssl_certificate /etc/letsencrypt/live/media.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/media.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Increase upload size for posters, etc.
client_max_body_size 20M;
# Upstream Jellyfin (local)
set $jellyfin 127.0.0.1;
location / {
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;
proxy_buffering off; # better for streaming
}
# WebSocket endpoint
location /socket {
proxy_pass http://$jellyfin:8096;
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;
}
}
EOF
# Enable the site and get a certificate
sudo ln -s /etc/nginx/sites-available/jellyfin /etc/nginx/sites-enabled/jellyfin
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d media.example.com --redirect -m you@example.com --agree-tos -n
# Lock down the firewall for public access via HTTPS only
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw deny 8096/tcp
sudo ufw enable
sudo ufw status
In Jellyfin Dashboard → Networking, add your reverse proxy to Known Proxies (e.g., 127.0.0.1
and your server’s private IP). This ensures client IPs are passed correctly through Nginx.
Step 5 — Create Users & Manage Libraries
- Go to Dashboard → Users → + to add family/teammates. Assign libraries and playback permissions.
- Use Dashboard → Libraries to add or rescan folders as you upload media to
/srv/media
. - For remote streaming, keep originals reasonable in size/bitrate or pre-encode to H.264/H.265 for smoother playback on modest CPUs.
Optional: Service & Updates
# Check service status / logs
sudo systemctl status jellyfin --no-pager
journalctl -u jellyfin -n 100 --no-pager
# Update Jellyfin when new releases arrive
sudo apt update && sudo apt -y upgrade
Troubleshooting
- Can’t reach HTTPS site: Confirm DNS points to your server; re-run Certbot and check
sudo nginx -t
andjournalctl -u nginx
. - Direct port works but proxy fails: Verify Nginx site is enabled and Jellyfin is listening on
8096
; restart both services. - Wrong client IPs: Add Nginx to Known Proxies in Jellyfin networking settings and reload.
- Playback stutters: Prefer direct play/stream-copy codecs and wired networking; reduce transcode quality if CPU is saturated.
Ready to stream? Launch on an instant, low-cost ServerStadium dedicated server for reliable bandwidth and storage.
Conclusion
You now have a secure Jellyfin media server with user accounts and HTTPS, ready for movies, TV, and music—hosted on fast, dependable ServerStadium hardware. For more help or information about ServerStadium services, visit our knowledge base or the ServerStadium website.