Plex Media Server for OpenWrt

I wrote an init.d script that will setup + install + control + update a Plex Media Server instance running on an ARM-based OpenWrt router that will serve media stored on a usb-attached external hard drive.

THE CODE is hosted on github. Refer to the README on github for more detailed info, but I will briefly summarize a few important points below.


REQUIREMENTS

You need a fairly beefy (quad core) ARMv7 or ARMv8 based router that has at least ~120 MB of RAM that it can dedicate solely to the Plex Media Servcer instance and that has at least 1 usb port (preferably usb 3). You will also need the software/kmods to mount the external drive, to unzip *.zip files, and to both mount and create xz-compressed SquashFS filesystems.

The Dynalink WRX36 is probably the cheapest device ($80 on amazon) that meets this criteria. I have one of these and can confirm it works (quite well) on the WRX36.


INSTALLATION

UPDATE: Ive re-worked how plex media server initializes things to hopefully make it easier to get things set up and also to make service plexmediaserver enable work as intended.

To get things started, the only thing you should need to do is create a directory .plex/Library near the top of the external drive you want the plex media server library stored on. Putting this at the drive's top-level directory is preferable, but 1 or 2 under the top level directory will work as well. Once this directory exists, run

service plexmediaserver start

and the plexmediaserver init script will automatically do the rest of the setup for you.

NOTE: you can override the automatic logic for determining the block device and mount point of the external drive with the plex library on it using the plexmediaserver UCI config entries for plex_drive_dev and plex_drive_mnt. See the README on github for more info.


USAGE

Everything is controlled by a init.d service. The main commands you will need are:

service plexmediaserver start: this will start plex media server
service plexmediaserver stop: this will stop plex media server
service plexmediaserver update: this check for new plex media server versions and (if available) update
service plexmediaserver enable: this will auto-start plex media server on boot.
service plexmediaserver disable: this will prevent auto-starting plex media server on boot.

You can access the plex media server from a plex media player app or from a web browser by going to ${ROUTER_IP}:32400/web (e.g., 192.168.1.1:32400/web)


HOW IT WORKS

The init.d script downloads an ARM NAS Plex Media Server package, unpacks it, and makes an xz-compressed squashfs image of it that gets saved on the external drive. When you start plex, it copies this sqashfs image to the device and mounts it and then runs plex from the mounted squashfs image.

NOTE: you dont need to manually do these, they are automated.

  • downloading the firmware and generating the squashfs image is done by service plexmediaserver update.
  • transferring and mounting the squashfs image is handled by the service plexmediaserver start command

This keeps Plex Media Server responsive (much more so than running it directly off of the external drive) but keeps memory usage to a manageable only used ~80 MB of RAM (not counting the memory plex media server uses to run...in total itll be more like 100-120 mb runtime memory + 75-80 mb for the squashfs image--> up to ~200 mb total)

5 Likes

great work !
Please add this to a wiki page !
thanks !

What's the advantage of doing it this way over running PMS in a docker?

Admittedly I havent tried using PMS-on-docker-on-openwrt, but Id guess the main benefit is that by using an XZ-compressed squashfs image, the PMS "install size" is only ~76 mb (versus 350-ish mb uncompressed). This means that, for most routers powerful enough to run PMS reasonably well, it is small enough that when stsarting PMS you can copy to the router's RAM (on a tmpfs), mount it, and run PMS from there (which is exactly what my script does).

Note: total memory usage is 200 mb or so, since you also have 100-150 mb of runtime memory usage on top of the ~76 mb squashfs image

Correct me if Im wrong, but it looks like when using docker the PMS docker image is large enough that youd need to have it stored on the external drive and would have to run it from there. Now again I havent tried, but I have to believe that keeping the PMS binary and required libraries on RAM is (even after the cost of decompressing them) much faster than running them off of a usb-attached external hard drive.

I can say that I once had a netgear R9000 which has PMS in the official firmware (moving it over to openwrt is what originally inspired me to write this script). They kept the PMS install files on the external drive (not in a docker container, but on the drive) and ran PMS from the disk directly. The performance was terrible...it was basically unusable.

Using my method performance is good enough that for all PMS tasks except video transcoding (which is too much work for even fairly beefy ARM cpu's) you'd never know that it was running on-router and not on a dedicated x86 machine on your network.

1 Like

Thanks, appreciated.

I dont have editing access to the though if someone who does wants to add a page they are more than welcome to (or, alternately, a wiki admin feels like giving me editing access Ill add one myself).

Side note: Ive just (earlier today) finished pushing a good number of updates to the script.

These should (hopefully) make some of the setup/cleanup operations more robust and makes configuration almost 100% automatic - the only required setup is create a directory .plex/Library on the drive to indicate that the plex library should go there.

If the external drive already has a plex library on it then configuration is 100% automatic (though can still be manually overridden using the various UCI config options that the init script creates for plexmediaserver).

It is worth mentioning required packages before installing:

opkg update && opkg install unzip curl squashfs-tools-mksquashfs

1 Like

If I can get OpenWRT to install on a Raspberry Pi, is there any reason why I might not be able to use this?

Travelling by car with children in Europe and got stung with mobile charges last time as their Amazon Fires were streaming over mobile hotspots.

Hoping to load a Raspberry Pi with OpenWRT (to handle multiple WiFi connections) and Plex to serve videos stored on an SD card.

Grateful if anyone has any thoughts on this setup please!

make sure you have a backup uSD card plus disable transcoding and of course - don't use any PI below 4 - ideally a 5 as support just got merged in master

1 Like

Actually works perfectly on my Asus RT-AX59U. Turned off transcoding,

Configured monit to restart plexmediaserver in case it crashed (happened once for unknown reason)

Instruction on how to configure monit for Plex:

  1. Install:
opkg update && opkg install monit
  1. Create plex control file:
mkdir /etc/monit.d
cd /etc/monit.d
vim plex

Press i to start editing and paste the following (replace sda1 with your mount point if it is different):

check process plexmediaserver with pidfile "/mnt/sda1/.plex/Library/Application\ Support/Plex\ Media\ Server/plexmediaserver.pid"
    start program = "/sbin/service plexmediaserver start" with timeout 60 seconds
    stop program  = "/sbin/service plexmediaserver stop"
    if failed host 127.0.0.1 port 32400 with timeout 30 seconds for 5 cycles then restart
    if failed url http://127.0.0.1:32400/web/index.html with timeout 30 seconds for 5 cycles then restart

Press Esc, then write :wq to save the file and quit vim.

  1. Uncomment last line in /etc/monitrc so it looks this way:
###############################################################################
## Includes
###############################################################################
##
## It is possible to include additional configuration parts from other files or
## directories.
#
  include /etc/monit.d/*

To check syntax of control files, execute:

monit -t

You should see Control file syntax OK if no typos are made

  1. Reload and enable monit service:
service monit reload
service monit enable

If you wish to test monit in action, kill plexmediaserver and try to open http://192.168.1.1:32400/web

cd "/mnt/sda1/.plex/Library/Application Support/Plex Media Server"
kill -9 $(cat plexmediaserver.pid)

After a few refreshes you should see Plex is up and running again

Remember to stop monit during plexmediaserver update to avoid any weird behaviour:

service monit stop
service plexmediaserver update
service monit start
1 Like

Been scratching my head for awhile now but I'm getting this when starting plex

root@hikari-openwrt:~# service plexmediaserver start
setting up / checking / loading UCI config for plexmediaserver
Preparing plexmediaserver for use - extracting plex binaries and library files
/sbin/uci: Entry not found
Starting Plex Media Server
To access Plex from a web browser, go to: 192.168.88.1:32400/web
/etc/rc.common: line 330: /tmp/plexmediaserver/1.32.8.7639-fb6452ebf-aarch64/Plex Media Server: not found

NVM, had it working by cleaning up the directory and starting over again

Hello,

I currently run plex from a docker container, however I would like to try your script.

But I see that you have it configured to look for a block drive mounted on /mnt.

Could you make some modifications to the script so that it can be installed on a system with exroot?

As well as being able to specify that the media folder is on a remote rclone drive.

Thanks.