How to Install Plex Cloud

March 11, 2017

As promissed here are the instructions on how I got Plex to work on the Cloud

Provider

I'm going to illustrate what I have done using Vultr, there is no reason why I picked it over another, I just happened to have the account open with them and ready to get it going.

The VPS I picked to start had the following specs at the time of this post:

  • OS: CentOS 7
  • CPU: 1 vCore
  • RAM: 2048 MB
  • Storage: 40 GB SSD
  • Bandwidth: 2000 GB (2TB)
  • Monthly Cost: $10

  • Datablock: 50Gb (currently free)

Server Setup

After the VPS is ready, and you can SSH into it we can start configuring it, the steps below illustrate what needs to be done:

$ adduser -c "Plex Media Server User" -d /home/plex -s /bin/bash plex
$ passwd plex
$ visudo

When you run the visudo command add the line plex ALL=(ALL) ALL right below root ALL=(ALL) ALL so it looks like:

## Allow root to run any commands anywhere
root ALL=(ALL) ALL
plex ALL=(ALL) ALL

Blockstorage setup (in case you choose to use it)

Create partitions:

$ parted -s /dev/vdb mklabel gpt
$ parted -s /dev/vdb unit mib mkpart primary 0% 100%

Create filesystem:

$ mkfs.ext4 /dev/vdb1

Mount block storage:

$ mkdir /mnt/blockstorage
$ echo >> /etc/fstab
$ echo /dev/vdb1               /mnt/blockstorage       ext4    defaults,noatime 0 0 >> /etc/fstab
$ mount /mnt/blockstorage

Software Install

Before installing anything else it's good to run a general update so we're in the latest versions of the base packages so run these in the CLI:

$ yum update
$ yum install unzip fuse git
$ bash -c "$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)"

The last command will ask you several question and install PlexMediaServer for you as well as keep it updated by installing a cron script.

Configure PlexMediaServer using an SSH Tunnel

Since Plex requires you to access it through localhost to set it up we are going to create a ssh tunnel so we trick it into thinking we're accessing it locally.

Run the following command on your terminal:

$ ssh -N -p 22 [email protected][IP] -L 32400:localhost:32400

Then access PlexMediaServer on your browser using the URL

http://localhost:32400

The following information is available at https://github.com/ajkis/scripts/wiki/best-plex-rclone-mount-settings, thank you to the author for this great info:

Plex Server Transcoder settings

Segmented transcoder timeout: 120
Transcoder temporary directory: /dev/shm
Transcoder default throttle buffer: 600

Note: /dev/shm is 50% of your server ram and we want to avoid HDD I/O's. Last time I tested 15 concurrent transcoding sessions took 12GB of ram, but it depends on source media, Transcoder default throttle buffer and Transcoder quality setting.

Plex Server Library Settings

Empty Trash automatically after every scan: Disable

In case you have any kind of problems with your mount eg it gets disconnected Plex will delete all meta data and movie info essentially you will start from scratch if you leave this enabled.

Plex Database Optimization

If you have big library (and especially if plex.db is not on SSD) its worth expanding default cache size in plex database. With this changes the DB pages will be put into RAM to improve performance.
To change it follow this procedure (terminal):

1. apt update && apt install sqlite
2. sudo service plexmediaserver stop
3. sqlite3 -header -line "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" "PRAGMA default_cache_size = 1000000"
4. sudo service plexmediaserver start

Note: The default cache size depends how big your library is, but default sqlite page size is 2000.( 1 million pages in cache would take around 1.5GB of ram) You can check your current page count with:

sqlite3 -header -line "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" "PRAGMA page_count"

Configure Firewall

Create the file:

$ vi /etc/firewalld/services/plexmediaserver.xml

And paste the content below into it:

<?xml version="1.0" encoding="utf-8"?>
<service version="1.0">
  <short>plexmediaserver</short>
  <description>Plex TV Media Server</description>
  <port port="1900" protocol="udp"/>
  <port port="3000" protocol="tcp"/>
  <port port="5353" protocol="udp"/>
  <port port="32400" protocol="tcp"/>
  <port port="32410" protocol="udp"/>
  <port port="32412" protocol="udp"/>
  <port port="32413" protocol="udp"/>
  <port port="32414" protocol="udp"/>
  <port port="32469" protocol="tcp"/>
  <port port="8181" protocol="tcp"/>
</service>

Then we just have to add the service to the firewall and restart it:

$ firewall-cmd --permanent --add-service=plexmediaserver
$ firewall-cmd --permanent --zone=public --add-service=plexmediaserver
$ systemctl restart firewalld.service

Mount Remote Drive

  • rClone

    With rClone we have a choice of which Cloud Drive provider we want to use, some from the many supported are:

    • Google Drive
    • Amazon Cloud
    • Dropbox

    The first step is to install rClone:

    Fetch and unpack

    $ curl -O http://downloads.rclone.org/rclone-current-linux-amd64.zip
    $ unzip rclone-current-linux-amd64.zip
    $ cd rclone-*-linux-amd64

    Copy binary file

    $ sudo cp rclone /usr/bin/
    $ sudo chown root:root /usr/bin/rclone
    $ sudo chmod 755 /usr/bin/rclone

    Install manpage

    $ sudo mkdir -p /usr/local/share/man/man1
    $ sudo cp rclone.1 /usr/local/share/man/man1/
    $ sudo mandb 

    Run rclone config to setup. See rclone config docs for more details.

    $ rclone config

    Mount Script

    We want our drive to mount at boot, and for that we'll create a simple script that runs when at startup:

    $ vi /home/plex/Scripts/rclonemount.sh

    Paste the below into the file make sure you replace $REMOTE: $MOUNTPOINT with your values and save it.

    #!/bin/sh
    /bin/fusermount -uz $MOUNTPOINT
    /usr/bin/rclone mount --read-only --allow-other --acd-templink-threshold 0 --stats 1s --buffer-size 1G -v --log-file=/path to/logfile.log $REMOTE: $MOUNTPOINT &
    exit

    Note: buffer-size is per file requested eg 10 streams will eat 10GB of your ram so set it accordingly. The bigger buffer just means users will be able to seek a bit further without buffering. ( The default rclone buffer is 16M )

    I got the mount settings from https://github.com/ajkis/scripts/wiki/best-plex-rclone-mount-settings, thank you to the author for this great info.

    Add to crontab on Plex User

    $ crontab -e

    And paste the following line:

    @reboot /home/plex/Scripts/rclonemount.sh > /home/plex/Logs/rclonemount.log 2>&1

    Configure Cron to Start After the Network is Up

    We want to run our cron script after the Network is up, so that when rClone attempts to mount the drive it can connect.

    $ systemctl enable NetworkManager-wait-online
    $ vi /lib/systemd/system/crond.service

    And add to the file the lines below, the Requires line will probably be new, but the After= should be there so just add to the end of it.

    Requires=network.target
    After=[...] network.target
  • node-gdrive-fuse:

    NodeJS:

    1. yum install git unzip fuse fuse-devel fuse-libs nodejs
    2. yum groupinstall "Development Tools"
    3. git clone https://github.com/thejinx0r/node-gdrive-fuse.git
    4. cd node-gdrive-fuse
    5. npm install
    6. cd src
    7. copy the config.json.sample to config.json and edit it as required.
    8. node client.es6.js (1st time only)
      1. On first load, you will be presented with a link to a google authentication page
      2. Visit this link and follow the steps to authenticate your account to allow GDriveFS to access your files.
      3. Copy the access code as indicated by the pop up window and paste it in the terminal. Press enter and it should say "Access Token Set".
      4. On first load: echo -e "\nuser_allow_other\n" >> /etc/fuse.conf
    9. node fs.es6.js &

    Unmounting

    To unmount: fusermount -u YOUR_PATH

Optional

The steps below are extra, I also install PlexPy and PlexRequest on the same server.

Install PlexPy

First we'll clone the repository and then create the systemd service file so we can use it to start / stop the application.

$ cd /opt
$ git clone https://github.com/JonnyWong16/plexpy.git
$ vi /lib/systemd/system/plexpy.service

And paste the codeblock below into it:

[Unit]
Description=PlexPy - Stats for Plex Media Server usage

[Service]
ExecStart=/opt/plexpy/PlexPy.py --quiet --daemon --nolaunch --config /opt/plexpy/config.ini --datadir /opt/plexpy
GuessMainPID=no
Type=forking
User=plex
Group=plex

[Install]
WantedBy=multi-user.target

To start the service run the following command:

$ systemctl start plexpy

And to enable it to run on boot:

$ systemctl daemon-reload
$ systemctl enable plexpy.service

Plex Logs Folder for PlexPy config:

/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/Logs/

Install PlexRequest

As the root user we'll install meteor

$ curl https://install.meteor.com/ | sh

Then we'll continue the installation as the plex user:

$ su plex
$ git clone https://github.com/lokenx/plexrequests-meteor.git plexrequests
$ cd plexrequests/
$ meteor

When Meteor has finished initializing, visit the url below to create the administrative ID using the same ssh tunnel technique above or just access it using yout server IP address direct:

http://localhost:3000/admin

After you're done with the Admin user creation cancel the script execution so you can continue with the setup.

To have it run on boot we'll need to create a systemd service for it, so as the root user:

$ vi /lib/systemd/system/plexrequest.service

Paste the block below into the file and save it.

[Unit]
Description=PlexRequest
After=network.target

[Service]
User=plex 
Type=simple
WorkingDirectory=/opt/plexrequests
ExecStart=/usr/local/bin/meteor
KillMode=process
Restart=always

[Install]
WantedBy=multi-user.target

To start the service run the following command:

$ systemctl start plexrequest

And to enable it to run on boot:

$ systemctl daemon-reload
$ systemctl enable plexrequest.service

Posted: Mar 11, 2017