Plex - zbrewer/homelab GitHub Wiki
I installed Plex in an unprivileged container in Proxmox in order to isolate it from the rest of my services and network. The host Proxmox server required some initial configuration in order to provide media files and other capabilities as described below. Note that these steps prevent snapshots of the container from being taken and do open up some permissions on the host Proxmox machine for the container/guest. That being said, this is still preferable to running an unprivileged container. If mounting the SMB share directly in the guest is acceptable, a VM can be used instead of a container and PCI passthrough can provide GPU access for hardware transcoding (SR-IOV must be supported by the GPU in order to still use it in the host or in other VMs).
The host NIC is connected to a trunk port and has access to, at a minimum, the servers
and DMZ
VLANs. This will allow the Plex server to be placed on the DMZ
VLAN while other services can run on servers
. Furthermore, firewall rules, or some other method, must allow access to the Samba share containing media files. This share will be mounted in the host to prevent any direct access from the Plex CT to non-DMZ networks.
The media
SMB share will be mounted in the host at /mnt/bindmounts/media
and this directory must first be created. A new group with access to the directory must also be created. This group can be called media-readers
and should have a GID greater than 100000 since Proxmox CT group IDs map into the host as the guest GID + 100000. In this example, I assigned the GID 101000. These steps can be accomplished with the following commands:
$ mkdir /mnt/bindmounts
$ mkdir /mnt/bindmounts/media
$ groupadd -g 101000 media-readers
From there, /etc/fstab
must be edited to contain the following lines (at the end of the file):
# Mount the media CIFS share for use by Plex
//10.0.20.10/media /mnt/bindmounts/media cifs ro,credentials=/root/.media_credentials,uid=root,gid=media-readers,file_mode=0550,dir_mode=0550,x-systemd.after=network-online.target,x-systemd.automount 0 0
This specifies the server address (10.0.20.10 in the example above), the share name (media), the mount location (the directory that was created above), the fact that this is a cifs/Samba share, specifies that it should be mounted as read only (ro instead of rw), provides the location of a file with the credentials to use, specifies the user and root that own the mounted directory, specifies the unix file permissions, specifies that the mount shouldn't be attempted until after the network is online (prevents mount errors at boot), and specifies that the mount should happen automatically.
After the fstab is edited, the credentials file specified (/root/.media_credentials
in the above example) should be created. Since this contains the login credentials for the Samba server, read permissions should be limited. The contents of this credentials file should be formatted as below (with <username>
and <password>
replaced by the appropriate values).
username=<username>
password=<password>
At this point, the mount -a
command can be run to try to mount the SMB share. Listing the directory contents of the media directory should now work, and ls -l /mnt/bindmounts
should show the ownership and permissions set in fstab. Rebooting can also be tested to ensure that the mount is created automatically, as expected.
A basic, unprivileged, container should be created in Proxmox into which Plex can be installed. This is mostly a typical setup although the network should be configured to place the container on the DMZ VLAN (if desired). Ubuntu and Debian are good Linux Distribution choices. Start the container and update it normally through the package manager.
With that done, create a new group with the GID of media-readers (the group we created earlier in the host), minus 100000, and add the root user (or the one you are using) to the new group. In this case, the commands would be:
$ groupadd -g 1000 media-readers
$ usermod -a -G media-readers root
Create a mount point for the media directory in the client (such as /mnt/media) and then shut the client down. Edit the LXC configuration in the file per the instructions in the Proxmox manual. In this case, that would mean appending the following line:
mp0: /mnt/bindmounts/media,mp=/mnt/media
Next, start the container back up and check that the /mnt/media
directory exists and can be listed by the root user. The ls -l /mnt
command should show that the group for the media
directory is media-readers
.
Plex can be installed per the installation guide on their website. Note that the .deb file can be fetched using wget by choosing all appropriate options on the download page and then right clicking the download button and selecting Copy link address
.
During the Plex install, a new plex
user is created that will need access to the media directory. Add this user to the media-readers
group:
$ usermod -a -G media-readers plex
From a machine (or a VM) on the same VLAN, visit <plex_ip_address>:32400/web
to complete setup including specifying the media locations.
Instructions here can be followed to enable updating Plex through the package manager (like other Linux packages).
Access to port 32400
will need to be opened in the firewall in order to allow access to Plex from other network segments and a port forward will need to be added for that same port in order to access the server remotely. When this is done, open the Remote Access
setting page in the Plex UI and manually specify/test the external port.
By default, Plex will not detect that other local subnets are in fact local and that the server can be connected to directly. This will cause a warning message in the UI and transcoding to a lower quality to occur. This can be fixed by going to the Network
setting page and showing advanced settings. Here, LAN networks will have to be specified including netmask. For example, 10.0.10.0/24,10.0.20.0/24,10.0.100.0/24,10.0.101.0/24
.
We also have to make sure that DNS lookups for plex.direct
return the local IP address of the Plex server. In the Unbound DNS server included with OPNsense (that I am using as my upstream DNS server), this can be accomplished in the web UI by going to Services > Unbound DNS > Overrides
and, on the Host Overrides
tab, adding an entry with *
for the host, plex.direct
for the domain, A (IPv4 address)
as the type, and the IP address of the Plex server as the value. Also, under Services > Unbound DNS > Advanced
the value plex.direct
should be added under Private Domains
.
After this, the DNS setup can be tested from Linux or Windows by running nslookup plex.direct
from the command line. The IP address of the Plex server should be returned (DNS caches may need to be cleared first).
Hardware transcoding in Plex requires a premium subscription and a compatible GPU. This generally means an Inte GPU/iGPU with QuickSync compatibility or an Nvidia GPU with NVENC support. The Wikipedia pages for each contain tables that show which codecs each hardware version supports.
PCI passthrough can be set up for VMs using the Proxmox instructions or one of a number of other guides (such as this one). The key for Intel GPUs (iGPUs especially) is to use Intel Graphics Virtualization Technology (GVT) which lets a single hardware GPU to be split into multiple virtual GPUs so that it can still be used in the host or in other VMs. Other GPUs will need SR-IOV (single-root input/output virtualization) in order to do this. Nvidia consumer GPUs specifically don't support this (although some workarounds may exist) so a GPU dedicated to the Plex VM is needed.
Underprivileged containers can access Intel iGPU QuickSync capabilities by mapping the render group and device from the host into the container. Instructions can be found here.