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)

7 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.

Not quite. Most of the configuration script is to allow for automatic self-configuration so that most users dont have to manually setup anything. If it is trying to configure itself itll assume it is under /mnt, but you can manually set this to wherever youd like and the script will use it.

Ive never tried it with extroot, but I think the script will work as is to run plex so long as you manually set a few UCI configs (the automatic self-configuration wont work with extroot). Again havent tried, but I think if you manually set the following 3 items in the plexmediaserver uci config it would probably work:

  1. uci set plexmediaserver.@main[0].plex_browser_root=<PATH> - this should be set to the path of the directory containing your plex library (it should contain .plex/library/...). I think having this be on a remote drive is fine, but it needs to be mounted to some path that exists on your local filesystem

  2. uci set plexmediaserver.@main[0].plex_drive_dev=/dev/<BLK_DEV> - set this to the block device (e.g., /dev/sda1) of your extroot drive

  3. uci set plexmediaserver.@main[0].plex_drive_mnt=<PATH> - set this to the mount point that /proc/mounts lists for the plex_drive_dev block device. As i understand extroot setups, this should (i think) be either /overlay or /rom/overlay

With these 3 manually set i think the script would work in an extroot setup

I tried to perform an installation with the instructions you gave me, but it threw several errors that I really don't understand.

I don't know if I'm doing something wrong or if I skipped installing a necessary package so that the script could run normally.

In any case this is the console log:

root@OpenWrt:~# /tmp/install_plex.sh /dev/sda1 /overlay
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 24803 100 24803 0 0 87992 0 --:--:-- --:--:-- --:--:-- 88582
setting up / checking / loading UCI config for plexmediaserver
/sbin/uci: Invalid argument
cfg017f6a
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/sbin/uci: Entry not found
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 34347 0 34347 0 0 38599 0 --:--:-- --:--:-- --:--:-- 38898
An Update for Plex Media Server is available!!
Current version:
New Version: 1.40.1.8227-c0dd5a73e-aarch64\n
Downloading 'https://downloads.plex.tv/plex-media-server-new/1.40.1.8227-c0dd5a73e/asustor/PlexMediaServer-1.40.1.8227-c0dd5a73e-aarch64.apk'
Connecting to 172.64.146.103:443
Writing to 'PlexMediaServer-1.40.1.8227-c0dd5a73e-aarch64.apk'
PlexMediaServer-1.40 100% |*******************************| 94569k 0:00:00 ETA
Download completed (96839532 bytes)
/etc/rc.common: line 444: unzip: not found
mv: can't rename 'data.tar.gz': No such file or directory
gzip: /overlay/.plex/Library/Application/0/1.40.1.8227-c0dd5a73e-aarch64/data.tar.gz: No such file or directory
tar: short read
mv: can't rename '/overlay/.plex/Library/Application/0/1.40.1.8227-c0dd5a73e-aarch64/data.tar.gz': No such file or directory
Parallel mksquashfs: Using 4 processors
Creating 4.0 filesystem on plexmediaserver.sqfs, block size 131072.
[| ] 0/0 100%

Exportable Squashfs 4.0 filesystem, xz compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,
compressed xattrs, compressed ids
duplicates are removed
Filesystem size 0.31 Kbytes (0.00 Mbytes)
101.28% of uncompressed filesystem size (0.30 Kbytes)
Inode table size 98 bytes (0.10 Kbytes)
100.00% of uncompressed inode table size (98 bytes)
Directory table size 74 bytes (0.07 Kbytes)
100.00% of uncompressed directory table size (74 bytes)
Number of duplicate files found 0
Number of inodes 3
Number of files 0
Number of fragments 0
Number of symbolic links 0
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 3
Number of hard-links 0
Number of ids (unique uids + gids) 1
Number of uids 1
root (0)
Number of gids 1
root (0)
mv: can't rename '/overlay/.plex/Library/Application/plexmediaserver.*': No such file or directory
Plex Media Server XZ-compresssed SquashFS (.sqfs) archive generated!. Archive is located at: /overlay/.plex/Library/Application/plexmediaserver.sqfs
setting up / checking / loading UCI config for plexmediaserver
/sbin/uci: Entry not found
/sbin/uci: Entry not found
/etc/rc.common: line 247: can't create /overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Stopping Plex Media Server (sending SIGQUIT)
cat: can't open '/overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGQUIT sent to server...waiting 3 seconds and sending SIGTERM if not dead
/etc/rc.common: line 260: can't create /overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running...SIGQUIT didnt work
Stopping Plex Media Server -- 2nd attempt (sending SIGTERM)
cat: can't open '/overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGTERM sent to Plex Media Server...waiting 3 seconds and sending SIGKILL if not dead
/etc/rc.common: line 274: can't create /overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running...SIGTERM didnt work
Stopping Plex Media Server -- 3rd attempt (sending SIGKILL)
cat: can't open '/overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGKILL sent to Plex Media Server.
/etc/rc.common: line 287: can't create /overlay/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running after being sent SIGKILL. Something is probably wrong.
You will need to manually kill Plex Media Server. Aborting.
setting up / checking / loading UCI config for plexmediaserver
/sbin/uci: Entry not found
/sbin/uci: Entry not found
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.0.1:32400/web
/etc/rc.common: line 330: /tmp/plexmediaserver/1.40.1.8227-c0dd5a73e-aarch64/Plex Media Server: not found

plexmediaserver has been installed and setup to automatically start up when the router boots

To manually start/stop plexmediaserver, use: service plexmediaserver [start|stop]

To update to a new plexmediaserver version, use: service plexmediaserver update

To access Plex from a web browser, go to: 192.168.0.1:32400/web

what does running

/sbin/uci show plexmediaserver

give you?

Also, you will probably need to run

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

Thanks, mate.
I got it done and the PMS is running just fine on my dual-core(a53) router.
No transcoding is required; the content is played in its original quality.
the system load is low when playing movie on the TV.

Is there a way to disable transcoding on this server? I noticed that some clients cannot load PGS subtitles, causing the server to transcode the subtitles.

It’s closed source and afaik it doesn’t have the option to completely disable transcoding. Not that that would you anyways. If the clients dont take PGS then you need to convert to SRT or in most cases just download the subtitles directly inside the Plex client.

I reverted the exroot configuration and mounted the external USB drive to /mnt/sda1 to try to install PMS.

I am currently running OpenWrt 23.05.3 on a Dynalink DL-WRX36 router.

The installation had some errors but apparently installed correctly.

Below is a log of the install script.

root@OpenWrt:/tmp# ./install_plex.sh /dev/sda1 /mnt/sda1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 24803  100 24803    0     0  66984      0 --:--:-- --:--:-- --:--:-- 68140
setting up / checking / loading UCI config for plexmediaserver
/sbin/uci: Invalid argument
cfg017f6a
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
 /sbin/uci: Entry not found
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 51296    0 51296    0     0  52013      0 --:--:-- --:--:-- --:--:-- 52289
An Update for Plex Media Server is available!!
Current version:
New Version:      1.40.2.8395-c67dce28e-aarch64\n
Downloading 'https://downloads.plex.tv/plex-media-server-new/1.40.2.8395-c67dce28e/asustor/PlexMediaServer-1.40.2.8395-c67dce28e-aarch64.apk'
Connecting to 172.64.146.103:443
Writing to 'PlexMediaServer-1.40.2.8395-c67dce28e-aarch64.apk'
PlexMediaServer-1.40 100% |*******************************| 94879k  0:00:00 ETA
Download completed (97156472 bytes)
Archive:  /mnt/sda1/.plex/Library/Application/0/PlexMediaServer-1.40.2.8395-c67dce28e-aarch64.zip
 extracting: control.tar.gz
 extracting: data.tar.gz
 extracting: apkg-version
Parallel mksquashfs: Using 4 processors
Creating 4.0 filesystem on plexmediaserver.sqfs, block size 131072.
[=====================================================================================================|] 3646/3646 100%

Exportable Squashfs 4.0 filesystem, xz compressed, data block size 131072
        compressed data, compressed metadata, compressed fragments,
        compressed xattrs, compressed ids
        duplicates are removed
Filesystem size 80053.17 Kbytes (78.18 Mbytes)
        42.67% of uncompressed filesystem size (187590.88 Kbytes)
Inode table size 22056 bytes (21.54 Kbytes)
        24.19% of uncompressed inode table size (91177 bytes)
Directory table size 26502 bytes (25.88 Kbytes)
        39.32% of uncompressed directory table size (67397 bytes)
Number of duplicate files found 114
Number of inodes 2674
Number of files 2417
Number of fragments 198
Number of symbolic links 0
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 257
Number of hard-links 0
Number of ids (unique uids + gids) 1
Number of uids 1
        root (0)
Number of gids 1
        root (0)
> mv: can't rename '/mnt/sda1/.plex/Library/Application/plexmediaserver.*': No such file or directory
Plex Media Server XZ-compresssed SquashFS (.sqfs) archive generated!. Archive is located at: /mnt/sda1/.plex/Library/Application/plexmediaserver.sqfs
setting up / checking / loading UCI config for plexmediaserver
> /sbin/uci: Entry not found
> /sbin/uci: Entry not found
> /etc/rc.common: line 247: can't create /mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Stopping Plex Media Server (sending SIGQUIT)
> cat: can't open '/mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGQUIT sent to server...waiting 3 seconds and sending SIGTERM if not dead
> /etc/rc.common: line 260: can't create /mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running...SIGQUIT didnt work
Stopping Plex Media Server -- 2nd attempt (sending SIGTERM)
> cat: can't open '/mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGTERM sent to Plex Media Server...waiting 3 seconds and sending SIGKILL if not dead
> /etc/rc.common: line 274: can't create /mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running...SIGTERM didnt work
Stopping Plex Media Server -- 3rd attempt (sending SIGKILL)
> cat: can't open '/mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid': No such file or directory
sh: you need to specify whom to kill
SIGKILL sent to Plex Media Server.
> /etc/rc.common: line 287: can't create /mnt/sda1/.plex/Library/Application Support/Plex Media Server/plexmediaserver.pid: nonexistent directory
Plex Media Server is still running after being sent SIGKILL. Something is probably wrong.
You will need to manually kill Plex Media Server. Aborting.
setting up / checking / loading UCI config for plexmediaserver
> /sbin/uci: Entry not found
> /sbin/uci: Entry not found
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: 172.31.0.1:32400/web


plexmediaserver has been installed and setup to automatically start up when the router boots

To manually start/stop plexmediaserver, use:             service plexmediaserver [start|stop]

To update to a new plexmediaserver version, use:         service plexmediaserver update

To access Plex from a web browser, go to:                172.31.0.1:32400/web

root@OpenWrt:/tmp# Error in command line:the argument for option '--serverUuid' should follow immediately after the equal sign
Crash Uploader options:

Minidump Upload options:
  --directory arg        Directory to scan for crash reports
  --serverUuid arg       UUID of the server that crashed
  --platform arg         Platform string
  --platformVersion arg  Platform version string
  --vendor arg           Vendor string
  --device arg           Device string
  --model arg            Device model string
  --allowRetries arg     Whether we will allow retries

Session Health options:
  --sessionStatus arg    Seassion health status (exited, crashed, or abnormal)
  --sessionStart arg     Session start timestamp in UTC or epoch time
  --sessionDuration arg  Session duration in seconds

Common options:
  --userId arg           User that owns this product
  --version arg          Version of the product
  --sentryUrl arg        Sentry URL to upload to
  --sentryKey arg        Sentry Key for the project

This is my config file (/etc/config/plexmediaserver)

config main
        option plex_browser_root '/mnt/sda1'
        option plex_drive_mnt '/mnt/sda1'
        option plex_drive_dev '/dev/sda1'
        option plex_library_dir '/mnt/sda1/.plex/Library'
        option plex_tmp_dir '/tmp/plexmediaserver'
        option plex_application_support_dir '/mnt/sda1/.plex/Library/Application Support'
        option plex_compressed_archive_path '/mnt/sda1/.plex/Library/Application/plexmediaserver.sqfs'
        option plex_version '1.40.2.8395-c67dce28e-aarch64'
        option plex_bin_dir '/tmp/plexmediaserver/1.40.2.8395-c67dce28e-aarch64'

The PMS works correctly even after restarting the router, so it seems that these errors do not affect its operation but I would like to know what causes these install errors.

NOTE: Installation with Exroot setup was not successful in any way.

I tried to run it just as you suggested, like this:

root@OpenWrt:/tmp# ./install_plex.sh /dev/sda1 /overlay

But there was no success.

Hopefully one day you will have enough time to try to adapt the script to work correctly with exroot. It would be great since there are no space limitations for OPKG.