If you’re interested, here’s a small’ish Python script which will automate some of what you’ve been doing manually. It’ll check what your DDNS domain resolves to, check to see if it is different than what is currently set in Plex, and change it if so. Optionally, it will restart the PMS service (or container) if a change has been made.
If you run it without any arguments it will tell you what you should need. In your case, you’d do something like:
./customurl.py -f plex.example.com -p path/to/Preferences.xml -c <container_name> -r
What this says is check the IP address of plex.example.com; read the contents of the Preferences.xml file at the designated path; if the custom server URL has changed, restart the container named ‘container_name’.
There are some limitations of this script:
- It does not back up your current Preferences.xml; do so yourself before running, if you decide to.
- It only supports one custom server URL. If you need to use multiple for some reason, it won’t work for that. (It would be relatively easy to add that, but doesn’t seem to be a common use case.)
- To be able to restart the Docker container (or systemd unit, if that’s how it’s run) you need root privileges; i.e. you need to
sudo it.
- It currently calls the docker or systemctl executable by hard-coded paths. They should be correct for most Debian-/Ubuntu-derived systems. Run
which docker or which systemctl to see where they really exist on your system. Adjust the last 4 lines lines as appropriate.
- If changes are made, a PMS service restart is required for them to take effect.
- This is a script which does in ~60 lines what could likely be done in half that with some more thought and optimization.
All that being said, it’s generally well-behaved; that bold warning in the first bullet is just a reminder to back Preferences.xml up first.
So, if you like, run it from the host (not the container) and for the -p/--path argument give the full path to the Preferences.xml file. At whatever path you mounted to /config in the container it will be ‘base_mount_path/Library/Application Support/Plex Media Server/Preferences.xml’
If you’re interested, save the following as ‘customurl.py’ on your system, make it executable, and give it a whirl.
#!/usr/bin/env python3
import os
import socket
import xml.etree.cElementTree as ET
import argparse
def getaddr(fqdn):
try:
addr = socket.gethostbyname(fqdn)
return addr
except Exception as e:
return None
def setcustomurl(prefs_path, ip, secure, port):
try:
tree = ET.parse(prefs_path)
root = tree.getroot()
current_url = root.get('customConnections')
except Exception as e:
return False
schema = "https" if secure else "http"
url = f"{schema}://{ip}:{port}"
if current_url == url:
return False
try:
root.set('customConnections', url)
except Exception as e:
return False
try:
tree.write(prefs_path)
except Exception as e:
return False
return True
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--path", help="Path to Preferences.xml", required=True)
ap.add_argument("-f", "--fqdn", help="Fully-Qualified Domain Name of Server", required=True)
ap.add_argument("-t", "--tcpport", help="Public port", default="32400")
ap.add_argument("-s", "--secure", help="Use HTTPS", action='store_true')
ap.add_argument("-c", "--container", help="Docker container name")
ap.add_argument("-r", "--restart", help="Restart Plex Media Server (requires root)", action='store_true')
args = ap.parse_args()
addr = getaddr(args.fqdn)
if addr is not None:
changed = setcustomurl(args.path, addr, args.secure, args.tcpport)
else:
print("Error setting custom URL, exiting...")
exit(1)
if changed and args.restart:
if args.container is not None:
arglist = ["docker", "restart", args.container]
os.execv("/usr/bin/docker", arglist)
else:
arglist = ["systemctl", "restart", "plexmediaserver"]
os.execv("/usr/bin/systemctl", arglist)
P.S. Ignore this whole thing and do the right way with @kesawi’s instructions above. Using a secure connection protected via a modern TLS certificate is better.