Jellyfin — Service Documentation

Self-hosted media server setup, configuration, and maintenance notes.

Architecture Overview

A simple Proxmox → LXC → Jellyfin stack keeps components isolated while mounting media from the host. This approach minimizes risk and makes the container easy to rebuild without touching data.

  • Proxmox VE runs on the bare metal and owns disks, networking, and hardware
  • LXC container provides a lightweight, isolated Linux environment
  • Jellyfin runs as a single service inside the container
  • Media storage is mounted into the container from the host
  • Clients connect directly to Jellyfin over HTTP/HTTPS

This design avoids nested storage complexity and keeps the container disposable. It isolates Jellyfin while keeping media management on the host for safety.

Container Design Decisions

LXC suits single-purpose services like Jellyfin thanks to low overhead and fast boot. Using an unprivileged container further reduces risk by mapping IDs rather than granting direct host access.

Why LXC Instead of a VM

  • Faster startup and lower overhead
  • Direct filesystem access via bind mounts
  • Easier backups and restores
  • Better suited for single-purpose services

Privileged vs Unprivileged

An unprivileged container is used to reduce risk. UID/GID mapping ensures the container cannot directly access host resources unless explicitly allowed.

Creating the LXC Container

Provision a lightweight container with enough CPU/RAM to serve streams and handle metadata. Keep the root disk small and treat the container as disposable—your media stays on the host.

  1. Upload a Debian 12 template in Proxmox
  2. Create a new container with the following baseline:
  • Hostname: jellyfin
  • Unprivileged: enabled
  • Memory: 2048–4096 MB
  • Cores: 2
  • Root disk: 8–16 GB
  • Network: vmbr0 with DHCP or static IP

Debian is chosen for stability and predictable package behaviour. It keeps upgrades consistent and reduces surprises during long-term operation.

Preparing the Container OS

Update packages and install base tools so the environment is consistent and secure. This prevents install issues and ensures TLS/cert utilities behave correctly.

After first boot:

apt update && apt upgrade -y
apt install -y curl gnupg2 ca-certificates lsb-release
          

This ensures the system is fully patched before installing Jellyfin. It also provides the tools needed for repository setup and secure downloads.

Installing Jellyfin

Enable the official Jellyfin repository to get trusted, up-to-date packages. Install the service and confirm it starts on port 8096 for local access.

Add the official Jellyfin repository:

curl -fsSL https://repo.jellyfin.org/install-debuntu.sh | bash
          

Install Jellyfin:

apt install -y jellyfin
          

The service starts automatically and listens on port 8096.

Storage Layout

Keep media on the host and mount it into the container via bind mounts to keep the container stateless. This simplifies backups and lets you rebuild Jellyfin without touching data.

Media is stored on the Proxmox host and exposed to the container using bind mounts.

Example host paths:

  • /tank/media/movies
  • /tank/media/tv
  • /tank/media/music

Bind mount configuration in Proxmox:

mp0: /tank/media,mp=/media
          

Inside the container, Jellyfin sees all media under /media.

External Storage (NAS)

If your media lives on a NAS, mount it on the Proxmox host and bind that path into the Jellyfin LXC. Prefer NFS on Linux for performance; SMB works well with Windows/Samba shares.

Option A — NFS (Recommended on Linux)

  • Create a host mount point: /mnt/nas/media
  • Add to /etc/fstab on Proxmox:
nas.example.local:/export/media  /mnt/nas/media  nfs4 \
  rw,noatime,_netdev,hard,intr  0  0
          

Note: In /etc/fstab this should be a single line. Remove the line breaks and backslashes when pasting.

Mount on the host, then bind into the container (Proxmox): mp0: /mnt/nas/media,mp=/media or via CLI: pct set <CTID> -mp0 /mnt/nas/media,mp=/media.

Option B — SMB/CIFS (Windows/Samba)

  • Install CIFS tools on the host: apt install -y cifs-utils
  • Store NAS credentials in /root/.smbcredentials (mode 600)
  • Add to /etc/fstab:
//nas.example.local/media  /mnt/nas/media  cifs \
  credentials=/root/.smbcredentials,iocharset=utf8,vers=3.1.1, \
  _netdev,nofail,dir_mode=0755,file_mode=0644  0  0
          

Note: In /etc/fstab this should be a single line. Remove the line breaks and backslashes when pasting.

Bind mount into the container the same way as NFS. Ensure the share is readable from an unprivileged LXC (see Permissions).

Jellyfin Library Setup

  • Point libraries at /media/movies, /media/tv, etc.
  • Disable “Scan on startup”; schedule scans off-peak.
  • Store metadata alongside media for portability.

Permissions & UID/GID Mapping

  • Unprivileged LXC maps container IDs to host IDs (offset 100000). Ensure the NAS share presents readable ownership/ACLs.
  • Samba tip: use “force user” or ACLs to present consistent ownership.
  • Inside the container, keep /media readable by Jellyfin.

Performance Tips

  • NFS generally outperforms SMB for Linux workloads.
  • Use noatime and avoid heavy SMB caching for metadata scans.
  • Keep NAS and container on the same VLAN for high bitrate streams.

Permissions & Ownership

Ensure file ownership and permissions align across host and container so Jellyfin can read media reliably. Misaligned UID/GID mappings are the most common cause of access errors.

Jellyfin runs as the jellyfin user. Ensure UID/GID alignment:

chown -R jellyfin:jellyfin /media
chmod -R 755 /media
          

If the host uses different IDs, adjust using Proxmox ID mapping or ACLs.

Initial Jellyfin Configuration

Walk through the first-run wizard to set admin credentials and add libraries from your mounted paths. Configure language, metadata preferences, and network exposure to fit your environment.

Access the web UI:

http://<container-ip>:8096
          

Configuration steps:

  • Create admin user
  • Add media libraries
  • Set preferred metadata language
  • Disable remote access if using a reverse proxy

Metadata & Library Behaviour

Favor portable metadata stored alongside your media so libraries survive container rebuilds. Local artwork and NFO files reduce rescans and keep matches accurate.

Recommended settings:

  • Enable NFO generation
  • Store artwork alongside media
  • Disable automatic deletion

This keeps metadata portable and version-controlled if needed.

Hardware Transcoding (Optional)

Hardware acceleration offloads video processing to the iGPU, enabling more concurrent streams with lower CPU usage. Pass through the device and enable VAAPI to take advantage of it.

If using Intel iGPU:

  • Pass /dev/dri into the container
  • Install intel-media-va-driver-non-free
  • Enable VAAPI in Jellyfin playback settings

This significantly reduces CPU usage during streaming.

Networking & Access

Choose how clients reach Jellyfin—direct LAN, reverse proxy, or VPN—based on your security model. Any public exposure must use HTTPS and sensible headers.

Common access patterns:

  • Direct LAN access
  • Reverse proxy via Nginx Proxy Manager
  • VPN-only access (WireGuard)

For public exposure, HTTPS is mandatory.

Backups & Maintenance

Back up Jellyfin config and portable metadata so you can recreate containers quickly. Keep the OS patched and Jellyfin updated to maintain performance and security.

Recommended backups:

  • Proxmox container snapshot
  • Jellyfin config directory: /var/lib/jellyfin
  • Media metadata (NFOs and images)

Updates:

apt update && apt upgrade -y
          

Operational Notes

Treat the container as stateless and focus on clean mounts from the host. Rebuilds and upgrades should be routine tasks that never endanger your media library.

  • Container can be destroyed and rebuilt without data loss
  • Media remains owned by the host
  • Jellyfin upgrades are non-disruptive

This setup scales cleanly and remains easy to reason about months later.