Hi All,
I thought I would share this for anyone else who may need it.
I am running a Scientific Linux 6.1 server and have both Plex Media Server and Plex Connect running on it quite happily. I have to change the Python WebServer.py script to use a different port as I already have Apache running other services on port 80, e.g. website, repos, etc. I also wanted to start and stop the Plex Connect services as a normal daemon so that it started up and shutdown automatically and kept running if I logged out of the server etc. Here's how I did it.
EDIT: This method does reply upon using the application 'screen' and is therefore a little more complicated than other solutions, but the tradeoff is that it does not require any code changes in a default installation of Plex Connect. This was one of the key requirements of this method so that upgrades would be simpler as you do not need to re-implement the code changes for every release you install. I chose to use screen as it is a commonly used application that has been around for quite a long time and is a mature and stable application that does what I needed to get PlexConnect running as a daemon / service.
EDIT: With some help from others on the forum I have also included instructions for Ubuntu users.
Prerequisites: Python 2.x series with being the 2.7 minimum version (Python 3.x is not supported)
Step 1. Install the Plex Connect scripts
Download and extract the Plex Connect Python Scripts into /usr/local/lib/plexconnect. Or use git to sync the files to your server if you prefer.
Do the usual modifications to Settings.cfg after running PlexConnect.py manually for the first time. In my case I modified the the IP of my PMS server, left the PMS port as it was correct for my installation of Plex Media Server and also left the DNS master settings to point to Google's DNS (8.8.8.8) as I was already using Google's DNS anyway and modified the Web Server port to listen on port 8080 in the Settings.cfg file.
Step 2. Some Optional Modifications WebServer.py and PlexConnect.py
Change Plex Connect Web Server Listening Port
EDIT: If you are not running a version of Plex Connect that allows you to configure the Web Server port in Settings.cfg and you need to run the Plex Connect Web Server on a port other than port 80 then this is relevant for you. But it is probably better to use a more up-to-date release of Plex Connect so that you don't need to modify any code.
To change the webserver to listen port to run on a different port, modify WebServer.py as shown below. I changed mine to run on port 8080 as I have repositories and other services running in Apache on port 80.
def Run(cmdQueue, param): #Protocol = "HTTP/1.0" # todo: IP, port try: server = HTTPServer(('',8080), MyHandler) server.timeout = 1 sa = server.socket.getsockname() except Exception, e: dprint(__name__, 0, "Failed to connect to port 8080 (http): {0}", e) sys.exit(1)
Modify user-agent Testing in WebServer.py
This is purely optional, I only did this to make it easier to test the installation was working through using a desktop browser. I reduced the user-agent testing in WebServer.py with this modification that I picked up from the forums (sorry I don't remember who originally posted it and couldn't find it again to link here). Once your installation is working you should not need this modification and it is nice to modify as little as possible from the distributed scripts as there is less to remember to change when you do an upgrade. So feel free to skip this step and only come back to it if you are having problems and need to test the installation by connecting directly to the Plex Connect web server with your desktop browser to see the XML output and confirm it is working as intended.
# Comment out original code # if self.headers['Host'] == Settings.getHostToIntercept() and \ # self.headers['User-Agent'].startswith("iTunes-AppleTV"): # Add the new code below if self.headers['User-Agent'].startswith(""):
Modify the log file path in PlexConnect.py
This is a purely optional change that you can make if you want to change the log file path and/or name. If it doesn't concern you then skip this.
I modified PlexConnect.py to make the log go to /var/log/PlexConnect.log because that's where I want my logs for all applications to go so I can manage them in one place using standard utilities such as logrotate etc. To do this make the changers below to PlexConnect.py
if __name__=="__main__": param = {} #param['LogFile'] = sys.path[0] + sep + 'PlexConnect.log' param['LogFile'] = '/var/log/PlexConnect.log' dinit('PlexConnect', param, True) # init logging, new file, main process
Step 3. Create an Apache Vhost
You should skip this step if you are just running the Plex Connect Script purely as shipped (listening on port 80) as it is not relevant for you. This step just makes Apache act as a proxy to accept connections on port 80 and send them to another port and/or host. For example if you are running Plex Connect's web server on a port other than port 80 this will allow your apple TV to connect to it by allowing Apache to accept the connection from the Apple TV on Port 80 and then connecting it to the host and port that you installed the Plex Connect web server on (i.e. Step 2 above).
I had to to add an Apache Name Based Virtual as I can't run PlexConnect on port 80 and therefore I need Apache to proxy connections to trailers.apple.com (on port 80) through to Plex Connect on port 8080 (see step 2 above). This allows Apache to continue hosting my other services and applications on port 80. This does rely on the mod_proxy modules being loaded into Apache. In my case they were already loaded as part of the default install so there was nothing for me to do. But if you have problems with this, refer to the Apache documentation for your Apache release.
Here is an extract of my configuration file (I called mine vhosts.conf) from /etc/httpd/conf.d. You need to modify the "your.server.name", "your.server.name.or.ip", and "your.server.alternate.names" to match your system. In the ProxyPass directives you will see that they point to port 8080. If you changed the port to something other than port 8080 in step 2, then these entries must also be updated to point to the correct port. The important entry is the second VirtualHost as it is the one that will accept the Plex Connect connect's from the redirected calls to trailers.apple.com. The first VirtualHost entry is just a blank one for any other sites you need. You can have multiple's of these as long as you do not re-use names in the ServerName and ServerAlias directives.
NameVirtualHost *:80<VirtualHost *:80>
# This is the default VHost
ServerName your.server.name
ServerAlias your.server.alternate.names
DocumentRoot /var/www/html
<VirtualHost *:80>
# This is the VHost for Plex Connect
ServerName trailers.apple.com
ProxyRequests Off
ProxyPreserveHost On<Proxy *> Order allow,deny Allow from all </Proxy> ProxyPass / http://your.server.name.or.ip:8080/ ProxyPassReverse / http://your.server.name.or.ip:8080/
EDIT: If you are running SELinux in enforcing mode, you will need to ensure that Apache is allowed to make network connections in order for the proxy directives to make Apache connect to Plex Connect. I did this by setting the httpd_can_network_connect flag in SELinux. Here is the command I used.
setsebool -P httpd_can_network_connect=1
Step 4. Add a init / startup script
Added an init script to start and stop the Plex Connect services as a proper daemon/service.
Note: To do this I used the 'screen' application. If you don't have screen, install it using yum (or it's equivalent on other distributions, e.g. apt-get)
yum install screen
EDIT: RHEL based Linux Distributions
Below is my init script, though I actually pulled out the variables in the top of the script and put them in a file /etc/sysconfig/plexconnect but for simplicity I added it all back to this one script for you. This script is saved as /etc/init.d/plexconnect.
#!/bin/bash ### BEGIN INIT INFO # Provides: plexconnect # Required-Start: plexmediaserver networking # Required-Stop: plexmediaserver networking # Default-Start: 3 4 5 # Default-Stop: 0 1 6 # Short-Description: This is the Plex Connect daemon # Description: This script starts the Plex Connect # Python scripts in a detached screen. ### END INIT INFOUsing the lsb functions to perform the operations.
. /lib/lsb/init-functions
Process name ( For display )
NAME=PlexConnect
Daemon name, where is the actual executable
DAEMON="/usr/bin/screen"
DAEMON_OPTS="-S PlexConnect -d -m /usr/local/lib/plexconnect/PlexConnect.py"
DAEMON_USER=“root”pid file for the daemon
PIDFILE=/var/run/PlexConnect.pid
If the daemon is not there, then exit.
test -x “$DAEMON” || exit 5
case $1 in
start)
Checked the PID file exists and check the actual status of process
if [ -e $PIDFILE ]; then
pidofproc -p $PIDFILE > /dev/null 2>&1If the status is SUCCESS then don’t need to start again.
if [ $? = “0” ]; then
log_success_msg “Starting the process $NAME”
exit # Exit
fi
fiStart the daemon.
Start the daemon with the help of start-stop-daemon
Log the message appropriately
if start_daemon -u $DAEMON_USER -p $PIDFILE $DAEMON $DAEMON_OPTS; then
while read line ; do [[ line =~ ([0-9]*).PlexConnect ]] && echo {BASH_REMATCH[1]} ; done < <(screen -ls) > $PIDFILE
log_success_msg “Starting the process $NAME”
else
log_failure_msg “Starting the process $NAME”
fi
;;
stop)Stop the daemon.
if [ -e $PIDFILE ]; then
pidofproc -p PIDFILE > /dev/null 2>&1 if [ "?" = 0 ]; then
killproc -p $PIDFILE
/bin/rm -rf $PIDFILE
log_success_msg “Stopping the $NAME process”
fielse
log_failure_msg “$NAME process is not running”
fi
;;
restart)Restart the daemon.
$0 stop && sleep 2 && $0 start
;;
status)Check the status of the process.
if [ -e $PIDFILE ]; then
pidofproc -p PIDFILE > /dev/null 2>&1 if [ "?" = 0 ]; then
log_failure_msg “$NAME PID file exists, but the process dead”
killproc -p $PIDFILE
/bin/rm -rf $PIDFILE
else
log_success_msg “$NAME process is running”
fi
else
log_failure_msg “$NAME process is not running” #log_end_msg 0
fi
;;
reload)
$0 restart
;;
*)For invalid arguments, print the usage message. echo “Usage: $0 {start|stop|restart|reload|status}”
exit 2
;;
esac
Now you need to make sure the script has the correct permissions and add it script as a service / daemon so that it starts automatically. Then start the daemon. To do this, make sure the permissions are correct and use chkconfig. If you are using the root user you do not need the ‘sudo’ command at the front of the commands below.
sudo chown root:root /etc/init.d/plexconnect sudo chmod 755 /etc/init.d/plexconnect sudo /sbin/chkconfig --add /etc/init.d/plexconnect sudo /sbin/service plexconnect start
EDIT: Ubuntu based servers
Thanks to @ReneV for testing and modifying the script to work on Ubuntu.
Below is the init script. This script is saved as /etc/init.d/plexconnect.
#!/bin/bash ### BEGIN INIT INFO # Provides: plexconnect # Required-Start: plexmediaserver networking # Required-Stop: plexmediaserver networking # Default-Start: 3 4 5 # Default-Stop: 0 1 6 # Short-Description: This is the Plex Connect daemon # Description: This script starts the Plex Connect # Python scripts in a detached screen. ### END INIT INFO # Using the lsb functions to perform the operations. . /lib/lsb/init-functions # Process name ( For display ) NAME=PlexConnect # Daemon name, where is the actual executable DAEMON="/usr/bin/screen" DAEMON_OPTS="-S PlexConnect -d -m /usr/local/lib/plexconnect/PlexConnect.py" DAEMON_USER="root" # pid file for the daemon PIDFILE=/var/run/PlexConnect.pid # If the daemon is not there, then exit. test -x "$DAEMON" || exit 5 case $1 in start) # Checked the PID file exists and check the actual status of process if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE "$DAEMON $DAEMON_OPTS" "$NAME process" && status="0" || status="$?" # If the status is SUCCESS then don't need to start again. if [ $? = "0" ]; then log_success_msg "Starting the process $NAME" exit # Exit fi fi # Start the daemon. # Start the daemon with the help of start-stop-daemon # Log the message appropriately if start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -p $PIDFILE -- ${DAEMON_OPTS}; then while read line ; do [[ $line =~ ([0-9]*).PlexConnect ]] && echo ${BASH_REMATCH[1]} ; done < <(screen -ls) > $PIDFILE log_success_msg "Starting the process $NAME" else log_failure_msg "Starting the process $NAME" fi ;; stop) # Stop the daemon. if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE "$DAEMON DAEMON_OPTS" "Stoppping the $NAME process" && status="0" || status="$?" if [ "$?" = 0 ]; then start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE /bin/rm -rf $PIDFILE log_success_msg ""Stopping the $NAME process"" fi else log_failure_msg "$NAME process is not running" fi ;; restart) # Restart the daemon. $0 stop && sleep 2 && $0 start ;; status) # Check the status of the process. if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE "$DAEMON $DAEMON_OPTS" "$NAME process" && exit 0 || exit $? log_success_msg "$NAME process is running" else log_failure_msg "$NAME process is not running" fi ;; reload) $0 restart ;; *) # For invalid arguments, print the usage message. echo "Usage: $0 {start|stop|restart|reload|status}" exit 2 ;; esac
Now you need to make sure the script has the correct permissions and add it script as a service / daemon so that it starts automatically. Then start the daemon. To do this, make sure the permissions are correct and use update-rc.d. If you are using the root user you do not need the ‘sudo’ command at the front of the commands below.
sudo chown root:root /etc/init.d/plexconnect sudo chmod 755 /etc/init.d/plexconnect sudo update-rc.d plexconnect defaults sudo /sbin/service plexconnect start
Step 5. Change Your Apple TVs DNS Configuration
In each Apple TV that you want to use Plex Conenct with you need to go into the Settings->General->Networking and then modify your existing network connection to manually configure a DNS server. Enter the IP address of your server that is running the Plex Connect scripts above for the DNS server.
If all this has worked for you then when you open the trailers app on your reconfigured Apple TV you should now see Plex Connect with your Plex Media Server’s content.
I have three non-jailbroken Apple TVs that are all working simultaneously without issues that I have noticed. Two of these are Gen 3 1080p Apple TVs and the third is a Gen 2 720p Apple TV. All the Apple TVs are running the latest Apple iOS firmware.
Hopefully this is useful for people and saves time in working out how to get Plex Connect running on Linux. The hardest part for me was working out how to run the PlexConnect.py script as a daemon due to the way it is written to remain open in the shell and stop all the processes again upon a key press. This was not great for running a daemon process as the script dies as soon as it is detached from a console (i.e. nohup). Though it works fine if you want to manually start and stop the processes yourself. Using screen worked well for me, though I daresay there are a bunch of smarter people than I who have worked out better ways to do this.