Technology Encyclopedia Home >How to Set Up Jellyfin Media Server on a Cloud Server — Your Own Netflix

How to Set Up Jellyfin Media Server on a Cloud Server — Your Own Netflix

I have a collection of movies and TV shows that I want to watch from multiple devices — laptop, phone, TV. Keeping them synchronized and accessible from anywhere was awkward until I set up Jellyfin.

Jellyfin indexes your media library, downloads metadata and cover art, organizes everything into a polished interface, and streams to any browser or app. The free Jellyfin clients are available for basically every platform.

The server-side transcoding capability matters here: without it, your client needs to be able to play the original format directly. With it, Jellyfin converts the video in real time to something your device can handle. That's more CPU-intensive, which affects server sizing — I'll explain the trade-offs.

This guide deploys Jellyfin on Ubuntu 22.04 using Docker, with Nginx as the reverse proxy and HTTPS.

I run Jellyfin on Tencent Cloud Lighthouse. For streaming, bandwidth matters more than CPU for direct play. Lighthouse's bandwidth packages (200GB+ per month on standard plans) handle streaming video comfortably for personal use. For hardware transcoding of 4K content, you'll need more CPU power. The CBS cloud disk expansion is also useful here — you can attach additional storage for your media library as it grows, without migrating the Jellyfin configuration and database.


Table of Contents

  1. Jellyfin vs Plex
  2. Prerequisites
  3. Part 1 — Server Setup
  4. Part 2 — Deploy Jellyfin with Docker
  5. Part 3 — Configure Nginx Reverse Proxy
  6. Part 4 — Enable HTTPS
  7. Part 5 — Initial Setup and Library Configuration
  8. Part 6 — Upload Media Files
  9. Part 7 — Client Apps
  10. Part 8 — Backups
  11. The Gotcha: Direct Play vs Transcoding
  12. Jellyfin Maintenance Commands

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

Jellyfin vs Plex {#vs-plex}

Jellyfin Plex
Cost Free forever Free tier + Plex Pass ($5/mo)
Data privacy 100% self-contained Plex servers collect metadata
Remote streaming Free Requires Plex Pass
Mobile apps Free Free for local, Plex Pass for remote
Hardware transcoding Free Requires Plex Pass
Active development Yes (community) Yes (commercial)

Prerequisites {#prerequisites}

Requirement Notes
Cloud server Tencent Cloud Lighthouse — select Docker CE application image for fastest setup
Docker + Compose Pre-installed with Docker CE image; or install manually
Storage At least 50 GB for media; add a data disk for large libraries
Domain name For remote access via HTTPS

Part 1 — Server Setup {#part-1}

💡 If you selected the Docker CE application image, Docker is already running. Skip the Docker install lines below — start from sudo apt install -y nginx.

ssh ubuntu@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

sudo apt install -y nginx
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

# Create media directories
sudo mkdir -p /media/{movies,tvshows,music,photos}
sudo chown -R ubuntu:ubuntu /media

Part 2 — Deploy Jellyfin with Docker {#part-2}

mkdir -p ~/apps/jellyfin && cd ~/apps/jellyfin

Create docker-compose.yml:

version: '3.8'

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    ports:
      - "8096:8096"     # HTTP
      - "8920:8920"     # HTTPS (optional — we use Nginx instead)
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /media:/media:ro      # Media directory (read-only for security)
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    devices:
      - /dev/dri:/dev/dri   # For hardware transcoding (Intel/AMD GPU); comment out if not applicable
docker compose up -d
docker compose logs -f
# Wait for: Startup complete

Part 3 — Configure Nginx Reverse Proxy {#part-3}

sudo nano /etc/nginx/sites-available/jellyfin
server {
    listen 80;
    server_name media.yourdomain.com;

    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:8096;
        proxy_http_version 1.1;

        # WebSocket support (required for Jellyfin sync play and remote control)
        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-Host  $host;

        proxy_buffering off;
        proxy_request_buffering off;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}
sudo ln -s /etc/nginx/sites-available/jellyfin /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Part 4 — Enable HTTPS {#part-4}

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d media.yourdomain.com

Part 5 — Initial Setup and Library Configuration {#part-5}

Visit https://media.yourdomain.com.

The Jellyfin setup wizard:

  1. Select language

  2. Create admin user — username and password

  3. Add media libraries:

    • Click Add Media Library
    • Content type: Movies
    • Name: Movies
    • Folder: /media/movies
    • Click OK

    Repeat for TV Shows (/media/tvshows), Music (/media/music), Photos.

  4. Metadata language — select your preferred language

  5. Remote access — allow remote access (required for streaming outside home)

Jellyfin will scan your media directories and fetch metadata (posters, descriptions, episode info) from online databases.


Part 6 — Upload Media Files {#part-6}

SCP from local machine

# Upload movies
scp "My Movie (2024).mkv" ubuntu@YOUR_SERVER_IP:/media/movies/

# Upload entire folder
scp -r ~/Movies/ ubuntu@YOUR_SERVER_IP:/media/movies/

rsync (recommended for large libraries)

rsync -avzP --progress ~/Movies/ ubuntu@YOUR_SERVER_IP:/media/movies/

File naming conventions

Jellyfin (like all media servers) relies on file naming for metadata lookup:

Movies:

/media/movies/
  ├── The Dark Knight (2008)/
  │   └── The Dark Knight (2008).mkv
  └── Inception (2010)/
      └── Inception (2010).mkv

TV Shows:

/media/tvshows/
  └── Breaking Bad/
      ├── Season 01/
      │   ├── Breaking Bad - S01E01 - Pilot.mkv
      │   └── Breaking Bad - S01E02.mkv
      └── Season 02/

Part 7 — Client Apps {#part-7}

Platform App Notes
Browser Any browser Access via URL
Android Jellyfin for Android Google Play / F-Droid
iOS Infuse (paid) or Jellyfin Mobile App Store
Apple TV Swiftfin App Store
Android TV Jellyfin for Android TV Google Play
Roku Jellyfin Roku Channel Store
Kodi Jellyfin for Kodi Kodi repository
Fire TV Jellyfin Amazon App Store

Connect any client: enter https://media.yourdomain.com as the server address.


Part 8 — Backups {#part-8}

Media files are the most important backup. The Jellyfin config/database is smaller but worth backing up too:

# Backup Jellyfin config (metadata, users, settings)
docker run --rm \
  -v ~/apps/jellyfin/config:/data \
  -v ~/backups/jellyfin:/backup \
  alpine tar czf /backup/jellyfin_config_$(date +%Y%m%d).tar.gz -C /data .

For media files, use rsync to a separate backup location (local drive, S3, etc.).


The Gotcha: Direct Play vs Transcoding {#gotcha}

Jellyfin has two modes for streaming video:

  • Direct Play — sends the original file to the client unchanged. Zero CPU overhead, perfect quality.
  • Transcoding — re-encodes the video in real-time to a format/resolution the client supports. CPU-intensive.

On a VPS without a GPU, transcoding is very slow. A 1080p h.265 transcode can easily max out 4 CPU cores.

Solutions:

  1. Encode your media in h.264 (more compatible — most clients direct play it)
  2. Use clients that support your formats (browsers support MP4/h.264 natively)
  3. Force direct play in Jellyfin settings: Dashboard → Playback → Transcoding → uncheck options
  4. Use hardware transcoding (Intel Quick Sync or AMD VCE if your server has integrated graphics)

Check if hardware transcoding is available:

ls /dev/dri/
# If renderD128 exists, hardware transcoding may be available

Jellyfin Maintenance Commands {#maintenance}

# Update Jellyfin
cd ~/apps/jellyfin
docker compose pull
docker compose up -d --remove-orphans

# Rescan library (also available from admin UI)
docker exec jellyfin bash -c "curl -s -X POST http://localhost:8096/Library/Refresh"

# View logs
docker compose logs -f jellyfin

# Check container resource usage
docker stats jellyfin

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

What video formats does Jellyfin support for streaming?
Modern media servers support most common formats. Direct Play (native format support by client) is preferred over transcoding. H.264 video in MKV or MP4 containers has the widest client support.

What's the difference between Direct Play and Transcoding?
Direct Play streams the original file to the client, requiring no server CPU. Transcoding converts the video in real-time to a compatible format, requiring significant server CPU.

How much bandwidth do I need for video streaming?
Blu-ray quality: 25–40 Mbps. 1080p: 8–25 Mbps. 720p: 3–8 Mbps. Lighthouse bandwidth packages support these rates. For multiple simultaneous streams, multiply accordingly.

How do I add media files to the server?
Upload via SCP/SFTP from your local machine, rsync from a NAS, or download directly on the server. The guide covers the recommended directory structure for automatic library scanning.

How do I access my media library from outside my home network?
Your media server runs on a cloud VPS with a public IP — it's accessible from anywhere. Set up HTTPS (covered in the guide) and use the appropriate client app or web interface.

Set up your private media server:
👉 Tencent Cloud Lighthouse — Bandwidth-ready VPS for media streaming
👉 View current pricing and promotions
👉 Explore all active deals and offers