Self-Hosting·8 min read·

Running Jellyfin for Your Own Media Library

Stream your own movies and shows with Jellyfin using Docker Compose, hardware-accelerated transcoding, metadata, and a secure Caddy reverse proxy.

NB

Netbay Infrastructure Team

Netbay Engineering

On this page

Jellyfin is the open-source answer to Plex and Emby: a media server that streams the films, series, and music you own to any screen, without subscriptions, tracking, or locked-down catalogues. It manages metadata, watches your library folders for changes, and transcodes media on the fly when a client cannot play the original codec.

The appeal is ownership. There are no per-stream fees, no mandatory account, and no library that gets yanked because a licensing deal ended. You point Jellyfin at a folder tree, it builds the rich posters and plot summaries, and every device on your network streams straight from your box. For families and media hoarders, that is a meaningful win over renting access to a catalogue.

Self-hosting Jellyfin is a great second project for a VPS once you have basic Docker and reverse-proxy experience. This guide covers a production-oriented Compose setup, sensible transcoding, and the networking that keeps a personal stream box tidy.

Jellyfin streaming path /media library (read-only) Jellyfin server scan+metadata transcode cache ./cache stream Caddy reverse proxy + TLS out to browsers, TVs, phones

The Library Layout

Jellyfin expects a clear, standard folder hierarchy so its scanners match filenames to metadata automatically. Keeping media outside the container means re-creating the stack never touches your files, and a tidy tree makes asset matching fast and reliable:

text
/media
  /movies/Inception (2010)/Inception (2010).mkv
  /shows/Breaking Bad/Season 01/Breaking Bad S01E01.mkv
  /music/Artist/Album/01 - Track.mp3

Correct naming avoids most metadata headaches. Jellyfin then pulls posters, ratings, and episode art from public providers the same way professional media servers do.

Keep your media on the largest, fastest volume the VPS can reasonably hold, because streaming is an I/O-heavy workload. The seek bar, thumbnail previews, and in-flight transcodes all read from this directory repeatedly, so High-Speed SSD storage keeps scrubbing smooth instead of stuttering over slower storage. If you outgrow the boot disk, you can attach an additional high-capacity volume and mount it at /media without touching the application.

It also pays to sort long-running series by season folders, because the scraper guesses titles and numbers from the filename structure. Doing this once at collection time saves you hours of fixing one mismatched episode at a time.

Compose Configuration

The stock image works for most setups. Pass the library mount read-only to keep writes confined to the config and cache volumes, which makes those two volumes the only things you need to back up:

yaml
services:
  jellyfin:
    image: jellyfin/jellyfin:10.9
    container_name: jellyfin
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Kolkata
      - JELLYFIN_PublishedServerUrl=https://media.example.com
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /media:/media:ro
    ports:
      - "127.0.0.1:8096:8096"
      - "8920:8920"
    restart: unless-stopped
    devices:
      - /dev/dri:/dev/dri

The PublishedServerUrl must match your public hostname or remote clients will try to reach an internal address, which silently breaks streaming away from home. The optional /dev/dri mapping enables GPU transcoding if your host exposes one, dramatically reducing CPU load during playback.

Transcoding Strategy

Most devices need a transcode at least once, so tune it rather than disable it. Set the transcode path in the dashboard to the cache volume and cap CPU usage in settings. For a headless box, it is often enough to set:

ini
; /config/encoding.xml (snippet)
<TranscodePath>/cache/transcodes</TranscodePath>
<EnableThrottling>True</EnableThrottling>
<ThrottleDelaySeconds>180</ThrottleDelaySeconds>
<HardwareAccelerationType>none</HardwareAccelerationType>

On CPU-only hardware, cap simultaneous transcodes to two and prefer hardware-friendly container formats like H.264 so the CPU is rarely needed. This keeps the box responsive even when several viewers are active at once.

Secure Remote Access

Do not expose Jellyfin's plain port to the internet. Put Caddy in front for TLS and consider an access token for remote clients:

caddyfile
media.example.com {
    reverse_proxy 127.0.0.1:8096
    encode gzip
}

Then restrict playback to authenticated users only and disable guest mode. Consider an extra layer of protection such as a proxy ACL or a VPN for your phone, since transcoding exposes the box to the broader internet and you want to control who can place streaming load on it.

Takeaway

Jellyfin gives you an ad-free, self-owned streaming library that plays on phones, TVs, and browsers from anywhere. Match storage to your media size and keep it behind a clean reverse proxy, and you have a personal Netflix with no fees and no catalogue limits.

You can host a Jellyfin box on a Netbay Ubuntu VPS with SSD storage that keeps seeks snappy — deployed in under 60 seconds at netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance