Quick answer
What this guide helps you do
Plan and deploy Jellyfin in a Proxmox Ubuntu VM, including media storage, Docker, networking, backups and hardware-transcoding decisions.
Jellyfin beginner path
New to Jellyfin? Follow this order.
These guides form the SmallGrid Jellyfin path: install it, fix folder access, solve empty libraries, reduce unnecessary transcoding, then choose the right mini PC.
Quick answer
The clearest beginner design is Jellyfin in Docker inside an Ubuntu VM:
Proxmox host
└── Ubuntu VM
├── mounted media storage
└── Docker
└── Jellyfin
This adds a virtualisation layer compared with bare-metal Ubuntu, but it gives a clean guest boundary and familiar Docker management.
Do not migrate a working media server merely because Proxmox is available. First decide how the VM will reach media, whether hardware transcoding is needed and how configuration will be restored.
Read How to Build a Docker Server Inside Proxmox before starting.
Choose where the media lives
Separate the Jellyfin system from the library.
| Storage method | Use case | Main caution |
|---|---|---|
| Network share mounted in VM | NAS or separate storage server | Availability, credentials and startup order |
| Virtual disk attached to VM | Storage managed as a Proxmox guest disk | Backup size and host-storage planning |
| Physical disk passed to VM | Guest needs direct control | Reduced host flexibility; confirm disk identity |
| LXC bind mount | LXC deployment only | UID/GID mapping and host coupling |
A VM cannot use an LXC bind mount. It needs a virtual disk, network filesystem or passed-through controller/device.
Do not format an existing media disk during setup. Confirm every device by model, serial, filesystem and mount before changing it.
Use How to Mount an Existing Linux Drive in Proxmox for preservation-first storage planning.
Decide whether transcoding matters
Direct Play avoids video transcoding when the client supports the media. Hardware acceleration matters when Jellyfin must convert video, tone-map HDR or handle unsupported codecs efficiently.
Before designing GPU passthrough:
- Test representative clients.
- Open Jellyfin playback information.
- Identify Direct Play, Direct Stream or Transcode.
- Record the stated transcode reason.
- Decide whether CPU transcoding is actually inadequate.
Use Jellyfin Direct Play vs Transcoding and How to Check Why Jellyfin Is Transcoding.
Build the Ubuntu VM
Create an Ubuntu Server VM with:
- a verified current ISO
- CPU and memory based on the expected workload
- a system disk separate from large media where practical
- VirtIO network attached to
vmbr0 - QEMU guest agent
- start-at-boot enabled after testing
Do not over-allocate all host resources. Proxmox itself and other guests need capacity.
Inside Ubuntu, update and inspect the network:
sudo apt update
sudo apt full-upgrade
sudo reboot
ip -brief address
ip route
Give the VM a stable reservation and confirm TCP 8096 is reachable only from intended networks.
Mount media in Ubuntu first
Mount the library at a documented guest path, for example /srv/media, and verify it before Docker starts:
findmnt /srv/media
df -hT /srv/media
find /srv/media -maxdepth 2 -type f | head
Test access using the same UID/GID or service context Jellyfin will use. Do not hide a permissions problem with chmod 777.
If the mount is unavailable, stop. Starting Jellyfin against an empty mount point can make the library appear missing and may cause other services to write into the VM system disk.
Deploy Jellyfin
Use Jellyfin’s current official container documentation and image. Keep:
- Compose file
- environment settings
- Jellyfin configuration
- cache/transcode path
- media mount definitions
under documented paths with appropriate ownership.
Validate and start:
sudo docker compose config
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs --tail=100
Open:
http://JELLYFIN_VM_IP:8096
Add libraries only after the guest media path is proven.
Add hardware acceleration later
Keep the first build simple. Prove software playback, storage and restart behaviour before adding a GPU.
For an Intel iGPU in a VM, the high-level path is:
- Enable VT-d/IOMMU in firmware and Proxmox.
- Confirm the GPU’s IOMMU group.
- Make a local-console recovery plan.
- Pass the PCI device to the VM.
- Install supported guest drivers.
- expose the render device to the Jellyfin container
- enable QSV or VA-API in Jellyfin
- verify with an actual transcode
Use How to Pass an Intel GPU Through to Jellyfin for the detailed risk controls.
Back up the right data
Back up:
- Jellyfin configuration and database
- Compose and environment files
- Ubuntu VM or a reproducible build record
- mount configuration
- library metadata if it is not reproducible
The media library itself needs an independent protection plan. Including terabytes of media in frequent VM backups may be impractical.
Stop Jellyfin or use an application-consistent method before copying an active database. Then perform an isolated restore test.
Reboot verification
Test in stages:
- Restart Jellyfin.
- Restart Docker.
- Reboot Ubuntu.
- Reboot Proxmox during a maintenance window.
- Verify storage before Jellyfin.
- Play representative media on important clients.
- Confirm Direct Play and one intentional transcode.
- Check logs and disk use.
findmnt /srv/media
systemctl is-active docker
sudo docker compose ps
df -hT
Common failures
Library is empty
Compare the Ubuntu mount path with the Docker bind mount and Jellyfin library path. Use Jellyfin Docker Volume Paths Explained.
Permission denied
Check every parent directory, UID/GID and container mapping with Jellyfin Ubuntu Folder Permissions.
Playback starts transcoding unexpectedly
Check the playback reason, client codec support, subtitles and audio before blaming Proxmox.
GPU appears in Ubuntu but not Jellyfin
Confirm the render device exists in the VM, then confirm Docker received it and the container user has permission.
Verification checklist
- The deployment type is documented.
- Media storage is proven before Docker starts.
- Existing disks were not reformatted.
- Jellyfin configuration is separate from media.
- Important clients have been tested.
- Transcode reasons are recorded.
- Guest and Proxmox reboots are verified.
- Configuration and media have appropriate backup plans.
- A restore has been tested.
This is a deployment guide, not a claim that SmallGrid’s recorded bare-metal Ubuntu media stack has been migrated to Proxmox.
Next: Jellyfin in a VM vs LXC vs Bare Metal. Return to What Is Proxmox VE?.
Official references: Jellyfin container installation and Jellyfin hardware acceleration.
Jellyfin guide cluster
More Jellyfin fixes and setup guides
These guides link the main Jellyfin setup, permissions, remote access, direct play, and hardware topics together.
Jellyfin 12 Upgrade Preparation: Backup, Plugins and Migration Checklist
Prepare a Jellyfin 10.10 or 10.11 server for Jellyfin 12. Check your version, create a restorable backup, audit plugins and plan the first startup safely.
Jellyfin on Ubuntu: Low-Power Setup, Media Folders and Reboot Checks
Build a reliable low-power Jellyfin server on Ubuntu. Install Jellyfin, mount storage, fix media access, favour Direct Play, measure power, and verify the server after reboot.
Give Jellyfin Access to Media Folders on Ubuntu
Fix Jellyfin permission denied errors on Ubuntu. Test the service user, find blocked parent folders, apply safe ACLs, verify inheritance, and check mounted-drive options.
Jellyfin Library Not Showing Files? 8 Checks That Fix It
Fix a Jellyfin library that is empty or missing media. Check mounts, Linux permissions, Docker paths, library folders, naming, scans and logs in the correct order.
Jellyfin Docker Permissions: Fix Media Folder Access and UID/GID Errors
Fix Jellyfin Docker permission denied errors. Check bind mounts, container paths, UID and GID values, read-only media access, active mounts, and file visibility step by step.
Jellyfin Direct Play vs Transcoding: CPU, Quality and Compatibility
Compare Jellyfin Direct Play, Direct Stream and transcoding. See CPU use, quality differences, common triggers and how to check the active playback mode.