PMS within container binding only localhost

Server Version#: plexinc/pms-docker:1.22.0.4163-d8c4875dd
Player Version#: NA

I’m running PMS via docker using bridge networking. I realize this is something like “hard mode”, but I have other problems with host networking I’m trying to avoid.

My container shows that PMS is binding 127.0.0.1:32400 within the container. This leads to not being able to forward any traffic to the container from outside the container making the server effectively useless.

My command to start the container:

podman run \
  --name plex \
  --no-healthcheck \
  --publish=32400:32400/tcp \
  --publish=1900:1900/udp \
  --publish=3005:3005/tcp \
  --publish=8324:8324/tcp \
  --publish=32410:32410/udp \
  --publish=32412:32412/udp \
  --publish=32413:32413/udp \
  --publish=32414:32414/udp \
  --publish=32469:32469/tcp \
  -e TZ=America/Denver \
  -e PLEX_CLAIM=... \
  -e ADVERTISE_IP=192.168.1.1:32400,externalip:32400 \
  -e ALLOWED_NETWORKS=192.168.1.0/24 \
  -h myhostname \
  -v /var/opt/plex/config:/config \
  -v /var/tmp/plex/transcode:/transcode \
  -v /var/opt/plex/data:/data \
  plexinc/pms-docker:1.22.0.4163-d8c4875dd

After the container is running I run:

podman exec -it plex /bin/sh

Then from within the container:

`apt update;apt install net-tools;netstat -tulpn’

And see:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:32600         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:39235         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:42569         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:32400         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:32401         0.0.0.0:*               LISTEN      -                   
udp        0      0 127.0.0.1:51925         0.0.0.0:*                           -                   
udp        0      0 127.0.0.1:54428         0.0.0.0:*                           -                   
udp        0      0 10.0.2.100:41545        0.0.0.0:*                           -                   
udp        0      0 10.0.2.100:41671        0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:47276           0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:32410           0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:32412           0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:32413           0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:32414           0.0.0.0:*                           -                   
udp        0      0 10.0.2.100:34263        0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:1901            0.0.0.0:*                           -    

My reading of that is that PMS will only respond to incoming requests on port 32400 when originating from within the container and targeting the loopback address (127.0.0.1). This is supported by curl commands run within the container:

# curl http://127.0.0.1:32400
<html><head><script>window.location = window.location.href.match(/(^.+\/)[^\/]*$/)[1] + 'web/index.html';</script><title>Unauthorized</title></head><body><h1>401 Unauthorized</h1></body></html># curl http://10.0.2.100:32400
curl: (7) Failed to connect to 10.0.2.100 port 32400: Connection refused

From outside the container:

curl http://localhost:32400
curl: (56) Recv failure: Connection reset by peer

Is there a way to tell PMS within the container to bind to all ip addresses/adapters?

Documentation seems to indicate that I can control this setting via the web interface. However, if I can’t get the container to take incoming traffic I can’t use the web interface - is there a matching file I could edit directly?

Looks like in has something to do with my config file - when I remove the mount to /config and let the container recreate the configuration I get proper binding on all addresses within the container…

Looks like there is a configuration file at /config/Library/Application Support/Plex Media Server/Preferences.xml which can contain:

<Preferences allowLocalhostOnly="1" .../>

Removing that attribute made the container bind on all adapters again. I don’t know how that property got there, I assume something about the various gyrations I’ve performed in the web settings on getting host networking and remote access working…

It appears that additionally the <Preferences secureConnections="0" .../> setting has some bearing on whether or not a curl request from the host system gets a response. I’m not clear on what this setting controls - I believe it is related to whether or not TLS is required. When that setting is present a curl http://localhost:32400 from the container host is met with an empty reply.

Are you setting network=host or is that undesirable ?
Default is NAT which adds the layer of complication.

I’m not using host networking - that is undesirable.

At this point it’s coming down to understanding what each entry in Preferences.xml does - I haven’t found any documentation on it.

PMS will bind to loopback (required for PMS operation) and the first ethernet adapter with Link and a valid Gateway (to the internet).

We later change that if needed.

The container does have a way out to the internet?
It should since it’s on top of host resources… except that… you’re not using HOST networking. You’ll need a route table entry

The container has no issue making outbound curl requests to arbitrary endpoints like curl https://www.google.com.

At this point with the default config file I’m seeing different responses from within the local network (Addresses within the 192.168.1.0/24 subnet) and addresses from the Internet at large. Local addresses get an XML document, remote addresses get a 200-level response with an HTML document that has a <title>Unauthorized</title> in the document body. I assume this is start of the setup workflow.

Stupid question. (please forgive) – X-Plex-Token attached to the curl ?

POST to claim and GET to query with PUT to update existing items ?

If the container can’t see Plex.tv then it will never authenticate which will always result in “Unauthorized”

If you want it all off for traffic on the same subnet, secureConnections="0" is correct.
Also add AllowedNetworks= to the Preferences so cross-subnet connections are allowed.

Thanks for asking. I have not been including X-Plex-Token because I’m not interested in authenticated-or-not, I’m just interested in whether or not I can get a connection established to the container.

At this point I’ve done the work myself to get everything connected, which I’ve tested now both inside and outside my local network. Once I’ve confirmed that I have the proper behavior for bandwidth throttling and transcoding behavior based on where the request originates from I’ll post my final (anonymized) configurations for the benefit of anyone else who wants to do something similar.

The <title>Unauthorized</title> is verification of the socket connection.

If that’s your goal, then you’ve achieved it.

If you want application level connection (meaningful data returned), you will need the token.

At this point I have a working setup with podman (though I’m pretty sure 'docker` will work exactly the same way) using bridge networking rather than host networking. My start command is essentially the same as the docks for the image under “Bridge Networking”:

#!/bin/bash
podman run \
  --name plex \
  --no-healthcheck \
  --publish=32400:32400/tcp \
  --publish=1900:1900/udp \
  --publish=3005:3005/tcp \
  --publish=8324:8324/tcp \
  --publish=32410:32410/udp \
  --publish=32412:32412/udp \
  --publish=32413:32413/udp \
  --publish=32414:32414/udp \
  --publish=32469:32469/tcp \
  -e TZ=America/Denver \
  -e PLEX_CLAIM=claim-abc-xyz \
  -e ADVERTISE_IP=192.168.1.1:32400,plex.myhost.org:32400 \
  -h plex.myhost.org \
  -v /var/opt/plex/config:/config \
  -v /var/tmp/plex/transcode:/transcode \
  -v /var/opt/plex/data:/data \
  plexinc/pms-docker:1.22.0.4163-d8c4875dd

In my config I use --no-healthcheck due to specific limitations of my host - in general I would recommend keeping health checks on. PLEX_CLAIM value comes from the image instructions as well:

You can obtain a claim token to login your server to your plex account by visiting https://www.plex.tv/claim

The ADVERTISE_IP are meant to provide both my internal network (192.168.1.1:32400) and anyone on the internet at large (plex.myhosts.org:32400) with an address that will work to reach the server. The volume mounts are essentially a convenience - they make it easy to manipulate files from outside the container.

After some trial-and-error I found that I needed to be careful with several settings in Preferences.xml:

  • secureConnections - this can make PMS respond with an empty response
  • allowLocalhostOnly - prevents binding to any adapter that is not loopback
  • LanNetworksBandwidth - determines whether traffic is considered remote or not. My LAN is on 192.168.1.0/24 and my containers get addresses on 10.0.0.0/16, so I have this set to 192.168.1.0/255.255.255.0,10.0.0.0/255.255.0.0 to properly detect my local traffic.

In retrospect these seem obvious, but it wasn’t clear to me when manipulating settings via the UI while trying to change container settings that the UI settings would control things like how the container bound adapters. Because I was sharing the same configuration volume across container configs this made troubleshooting hard.

When in doubt, throw out your entire /config directory and start over, building your PMS config from scratch after any major change to container startup.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.