Guides:
- http://youtube.com/watch?v=tWumbDlbzLY
- https://www.xda-developers.com/jellyfin-on-proxmox-guide/
- https://www.wundertech.net/installing-jellyfin-on-proxmox/
- https://jellywatch.app/blog/jellyfin-proxmox-lxc-vm-setup-gpu-passthrough-2026
Create LXC Container
Go here. Do that. EXCEPT. Use a Debian image, not Alpine. This container
will have a bit more heavy lifting to do so I gave it a meatier distro. Keep in mind the commands from
the Alpine LXC page should be translated into Debian - i.e. apk update ->
apt update and so on. Could be interesting to try it with alpine and see
how it works. Come back when it's done.
pveam available --section system | grep debian
pveam download local vztmpl/debian-13-standard_13.1-2_amd64.tar.zst
pct create 102 local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
--hostname jellyfin \
--memory 4096 \
--cores 4 \
--rootfs local-lvm:100 \
--net0 name=eth0,bridge=vmbr0,gw=192.168.1.1,ip=192.168.1.16/24 \
--ostype debian \
--unprivileged 0
Getting this far, I noticed an issue with logging in and changing users being very slow. A warning
received creating the container suggested this may be a problem: WARN: Systemd 257 detected. You may
need to enable nesting. Discussed
here. "Debian (like most distros nowadays) uses a modern systemd version that needs nesting."
Privileged + nesting is
not recommended. So, let's make this unprivileged for now. There may be issues later with
transcoding but we'll jump off that bridge when we come to it.
Always use --unprivileged 1 unless you have a specific reason not
to. Unprivileged containers run as a non-root user on the host, significantly limiting the damage from a
container escape.
Change to Unprivileged
pct stop 102 # Stop
vzdump 102 --dumpdir /var/lib/vz/dump # Backup
# INFO: starting new backup job: vzdump 102 --dumpdir /var/lib/vz/dump
# INFO: Starting Backup of VM 102 (lxc)
# INFO: Backup started at 2026-07-29 13:48:14
# INFO: status = stopped
# INFO: backup mode: stop
# INFO: ionice priority: 7
# INFO: CT Name: jellyfin
# INFO: including mount point rootfs ('/') in backup
# INFO: creating vzdump archive '/var/lib/vz/dump/vzdump-lxc-102-2026_07_29-13_48_14.tar'
# INFO: Total bytes written: 732723200 (699MiB, 89MiB/s)
# INFO: archive file size: 698MB
# INFO: Finished Backup of VM 102 (00:00:08)
# INFO: Backup finished at 2026-07-29 13:48:22
# INFO: Backup job finished successfully
# INFO: notified via target `mail-to-root`
pct destroy 102 # Destroy
# Logical volume "vm-102-disk-0" successfully removed.
pct restore 102 /var/lib/vz/dump/vzdump-lxc-102-2026_07_29-13_48_14.tar --storage local-lvm --unprivileged 1 # Restore as unprivileged
# recovering backed-up configuration from '/var/lib/vz/dump/vzdump-lxc-102-2026_07_29-13_48_14.tar'
# Logical volume "vm-102-disk-0" created.
# Logical volume pve/vm-102-disk-0 changed.
# Creating filesystem with 26214400 4k blocks and 6553600 inodes
# Filesystem UUID: 452ee4ae-646b-496e-abb6-1de552fa8c8d
# Superblock backups stored on blocks:
# 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
# 4096000, 7962624, 11239424, 20480000, 23887872
# restoring '/var/lib/vz/dump/vzdump-lxc-102-2026_07_29-13_48_14.tar' now..
# extracting archive '/var/lib/vz/dump/vzdump-lxc-102-2026_07_29-13_48_14.tar'
# Total bytes read: 732723200 (699MiB, 677MiB/s)
# merging backed-up and given configuration..
pct start 102 # Start
# WARN: Systemd 257 detected. You may need to enable nesting. # Still have this warning
# Task finished with 1 warning(s)!
Enable Nesting
In Proxmox UI, click the container > Options > Features. This will say “none”. You can change it here But you'll feel smarter if you use the command line. From here.
pct set 102 --features nesting=1
Check the UI again and it'll say “nesting=1”. Does it work?
pct stop 102
pct start 102
No warning about Systemd 257 this time. Log in. Change to root. No hangs.
Install Jellyfin
apt install curl
curl -s https://repo.jellyfin.org/install-debuntu.sh | bash
systemctl enable jellyfin
systemctl status jellyfin
Firewall rules
I'm using nftables to manage firewall rules. Install and
enable it so it comes up after reboot.
apt install nftables
systemctl enable nftables
Give it some rules to block everything except ssh and Jellyfin and some other essentials.
nft flush chain inet filter input # Start over
nft add chain inet filter input "{ type filter hook input priority filter; policy accept; }" # New input chain
nft add rule inet filter input iifname "lo" accept # Loopback
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ip protocol icmp limit rate 1/second burst 5 packets accept
nft add rule inet filter input tcp dport { 22, 80 } accept
nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 8096 ct state new accept
nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 8920 ct state new accept
nft add rule inet filter input drop
Check in browser: 192.168.1.16:8096. Now this needs to be
saved to a file to survive reboot.
{
printf '#!/usr/sbin/nft -f\n'
printf '\n'
printf 'flush ruleset'
printf '\n'
nft list ruleset
} > /etc/nftables.conf
Reboot to test. Create a directory for media e.g. /media/movies. If this
is in the user home directory, Jellyfin won't be able to see it. Copy media from dev machine to the
Jellyfin LXC. I tried scp a few times but it stalled and took out SSH.
Then I used rsync. This has to be installed on the LXC.
rsync -avz --progress * jellyfin:/home/damo/Movies
In the browser, create a library and add the directory where the files are. The client will not be able to see any files unless the directory is added to the jellyfin group and the user is made owner.
chown damo:jellyfin /media/movies
chmod 750 /media/movies
Now. Done.