Testing Out Plex with Docker
In my previous post I realized that you can’t bind a Plex instance to a specific IP. Some people have had luck accomplishing that with docker. I have heard many things about docker so I decided to give it a try.
Install Docker
Let’s install docker, I was using CentOS 7 and docker is part of the default repositories. So the following took care of installing docker:
sudo yum install docker
If you want regular users to be able to run containers it’s best to create a docker group and assign users to it. Here are some references:
Let’s add a group so users part of that group can run docker commands:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:35:45]
└─[6] <> sudo groupadd docker
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:35:58]
└─[0] <> sudo usermod -aG docker elatov
Then logout (and login back in) and make sure you are part of the group
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:37:01]
└─[0] <> groups
elatov wheel mail exim ossec docker
So let’s go ahead and start the docker service:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:30:48]
└─[1] <> sudo systemctl start docker
Getting a Docker Image
Now let’s get the docker image for centos7, the repo for that is here. To get the image we can use “docker pull”:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:37:02]
└─[0] <> docker pull centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... latest: Pulling from library/centos
47d44cb6f252: Pull complete
838c1c5c4f83: Pull complete
5764f0a31317: Pull complete
60e65a8e4030: Pull complete
library/centos:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:8072bc7c66c3d5b633c3fddfc2bf12d5b4c2623f7004d9eed6aae70e0e99fbd7
Status: Downloaded newer image for docker.io/centos:latest
To confirm the image is there we can use the “docker images” command:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 10:45:51]
└─[0] <> docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/centos latest 60e65a8e4030 7 days ago 196.6 MB
Creating a Custom Bridge Device for Docker
By default docker creates an internal bridge (docker0, more information about docker networking is here that doesn’t have an uplink and uses NAT capabilities from iptables to NAT traffic out or create port forwards (DNAT) to containers. Since Plex uses multicast for DLNA I decided to create a custom bridge which will allow containers direct access to the network. There are a couple of cool posts that discuss docker networking:
- Setting up a Docker Bridge
- Four ways to connect a docker container to a local network
- Docker Networking 101 – Host mode
- How to expose docker container’s ip and port to outside docker host without port mapping
If you want to assign static IPs to VMs there are a couple third party scripts which allow you to do that:
From the sound of it, the static IP feature will probably be part of docker soon though. I didn’t need static IPs as I was just playing around with the setup.
Instructions on how to create your own bridge are at Building your own bridge. First let’s install the bridge-utils:
sudo yum install bridge-utils
Now I ended up using ens160 as my uplink to the bridge and then creating a brdige device. Here are the files I ended up with:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:38:18]
└─[0] <> cat /etc/sysconfig/network-scripts/ifcfg-ens160
TYPE=Ethernet
BOOTPROTO=none
IPV6INIT=no
NAME=ens160
ONBOOT=yes
HWADDR=00:0C:29:A3:D4:FA
#IPADDR=192.168.1.100
#PREFIX=24
#GATEWAY=192.168.1.1
BRIDGE=br0
and here is the bridge device:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:38:29]
└─[0] <> cat /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
BOOTPROTO=none
IPV6INIT=no
NAME=br0
ONBOOT=yes
IPADDR=192.168.1.100
PREFIX=24
GATEWAY=192.168.1.1
DELAY=0
After a service restart:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:35:21]
└─[0] <> sudo systemctl restart network
I saw the following IP configuration:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:35:33]
└─[0] <> ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
inet 192.168.1.100/24 brd 192.168.1.255 scope global br0
valid_lft forever preferred_lft forever
and using the brclt and bridge commands I could confirm that my interface is attached to the bridge:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:35:39]
└─[0] <> brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c29a3d4fa no ens160
docker0 8000.0242471a6cf0 no
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:36:32]
└─[0] <> bridge link
2: ens160 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2
Enable Docker to Use Custom Bridge Device
Now let’s configure docker to use that bridge, first let’s disable the original bridge and iptables rules:
$ sudo systemctl stop docker
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0
$ sudo iptables -t nat -F POSTROUTING
then I modified the options to look like this
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:51:09]
└─[0] <> grep OPTIONS /etc/sysconfig/docker
OPTIONS='-b=br0 --ip-masq=false --iptables=false'
I disabled SNAT and DNAT settings since I didn’t need them any more. The options are covered here. And after starting up the docker daemon the other bridge was gone:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:51:38]
└─[0] <> sudo systemctl start docker
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:52:50]
└─[0] <> ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
inet 192.168.1.100/24 brd 192.168.1.255 scope global br0
valid_lft forever preferred_lft forever
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 11:52:54]
└─[0] <> brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c29a3d4fa no ens160
Running (and Getting Used) to Containers
Unlike VMs, containers don’t keep running after the main process you started has stopped (some docker basics are covered in Hello world in a container). For example let’s start a container from the centos image using interactive mode (this is the -it flags) and background it (that’s the -d flag):
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:07:00]
└─[0] <> docker run -it -d docker.io/centos /bin/bash
5276199a151dee39ad1dcf861969802316038ee09b4d32b9d2d5c11f213ce101
This way the docker container will keep running:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:17:41]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5276199a151d docker.io/centos "/bin/bash" 42 seconds ago Up 42 seconds clever_lovelace
You can then attach to that shell, by using the attach parameter:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:18:28]
└─[0] <> docker attach clever_lovelace
[root@5276199a151d /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:17 ? 00:00:00 /bin/bash
root 14 1 0 03:19 ? 00:00:00 ps -ef
Now if I type in exit the shell will stop and so will the container, instead if I type ctrl-P + ctrl-Q it will keep the shell running in the background:
[root@5276199a151d /]# %
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:20:07]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5276199a151d docker.io/centos "/bin/bash" 2 minutes ago Up 2 minutes clever_lovelace
I can also start another shell in the same container:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:20:54]
└─[1] <> docker exec -it clever_lovelace /bin/bash
[root@5276199a151d /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:17 ? 00:00:00 /bin/bash
root 15 0 0 03:21 ? 00:00:00 /bin/bash
root 27 15 0 03:21 ? 00:00:00 ps -ef
If exit out of this one the original shell will keep running:
[root@5276199a151d /]# exit
exit
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:21:41]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5276199a151d docker.io/centos "/bin/bash" 4 minutes ago Up 4 minutes clever_lovelace
Now if I attach back and exit out it will stop running:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:22:21]
└─[1] <> docker attach clever_lovelace
[root@5276199a151d /]# exit
exit
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:22:29]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
We can see the container is not longer running, but if we pass the -a paramer to the ps option we will see the non-running containers:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:22:31]
└─[0] <> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5276199a151d docker.io/centos "/bin/bash" 5 minutes ago Exited (0) 42 seconds ago clever_lovelace
But if we want, we can start it back up:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:23:11]
└─[0] <> docker start clever_lovelace
clever_lovelace
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:23:30]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5276199a151d docker.io/centos "/bin/bash" 5 minutes ago Up 3 seconds clever_lovelace
If we didn’t use the -it flag then the bash command would quit right away:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:24:34]
└─[1] <> docker run -d docker.io/centos /bin/bash
8fb31f991b12d58c1d129f8696b0950776d5b6f38e403b30b2052c393e4aec8b
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:24:57]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:25:01]
└─[0] <> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8fb31f991b12 docker.io/centos "/bin/bash" 10 seconds ago Exited (0) 9 seconds ago hungry_wilson
For some reason it took a while for me to get the concept that containers are not VMs. Another person had a similar question here.
Creating a Docker Image
Let’s create our own image from the centos one with Plex pre-installed (sample setup can be seen at Build your own images). First let’s launch the image and connect to it:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:29:40]
└─[0] <> docker run -it docker.io/centos /bin/bash
[root@17f3892da040 /]#
Now let’s install some tools and clean up the yum cache to save space:
[root@17f3892da040 /]# yum install iproute initscripts
[root@17f3892da040 /]# yum clean all
Now from the docker host let’s copy the init script
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:15:22]
└─[0] <> docker cp /etc/init.d/plexmediaserver berserk_rosalind:/etc/init.d/
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:34:19]
└─[0] <> docker cp /etc/sysconfig/PlexMediaServer berserk_rosalind:/etc/sysconfig/
Now let’s create the lock directory:
[root@17f3892da040 /]# mkdir -p /run/lock/subsys
And let’s add the user:
[root@17f3892da040 /]# groupadd -g 1000 plex
[root@17f3892da040 /]# useradd -u 1000 -g plex plex
Lastly let’s create the start up script and make sure it’s executable:
[root@17f3892da040 /]# ls -l /usr/bin/plex.sh
-rwxr-xr-x 1 root root 122 Jan 1 03:41 /usr/bin/plex.sh
[root@17f3892da040 /]# cat /usr/bin/plex.sh
#!/bin/bash
su -s /bin/sh plex -c ". /etc/sysconfig/PlexMediaServer; cd /usr/lib/plexmediaserver; ./Plex\ Media\ Server"
So let’s save/commit the current changes into a new image. First let’s exit the current container and it will stop it:
[root@17f3892da040 /]# exit
exit
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:38:32]
└─[5] <> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
17f3892da040 docker.io/centos "/bin/bash" 8 minutes ago Exited (5) 2 seconds ago berserk_rosalind
Now let’s create a new image from the stopped container:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:43:24]
└─[0] <> docker commit berserk_rosalind centos-plex
16e8ef5f55556df16e1e2477d17394093845e3d0bd6573f07c34bb5af50395f2
And let’s confirm the image is there:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:43:44]
└─[0] <> docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos-plex latest 16e8ef5f5555 6 seconds ago 255.4 MB
docker.io/centos latest 60e65a8e4030 7 days ago 196.6 MB
Running the Plex Docker Container
Plex wants some ulimits configured and luckily staring with Docker 1.6 you can pass in ulimits into a container (the parameter is described here). Since I have Plex installed on the host machine, I didn’t want to install it on the containers (this is definitely not best practice, but I was just playing around with the setup). So I decided to mount two folders from the host machine into the container:
- /usr/lib/plexmediaserver
- /var/lib/plexmediaserver
This is accomplished with -v flag to the “docker run” option. Now let’s start a new container from our brand new image and make sure we can start the init script. So here is start another container with using bash as the ENTRYPOINT/main process:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:47:17]
└─[0] <> docker run -v /usr/lib/plexmediaserver:/usr/lib/plexmediaserver -v /var/lib/plexmediaserver:/var/lib/plexmediaserver --ulimit memlock=3072000:3072000 --name=plex -it -h plex centos-plex /bin/bash
[root@plex /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:47 ? 00:00:00 /bin/bash
root 16 1 0 03:47 ? 00:00:00 ps -ef
Now still in our container we can start the plex service:
[root@plex /]# /etc/init.d/plexmediaserver start
Starting PlexMediaServer: [ OK ]
[root@plex /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:47 ? 00:00:00 /bin/bash
root 30 1 0 03:48 ? 00:00:00 su -s /bin/sh plex -c . /etc/sysconfig/PlexMediaServer;
plex 32 30 0 03:48 ? 00:00:00 sh -c . /etc/sysconfig/PlexMediaServer; cd /usr/lib/plex
plex 36 32 20 03:48 ? 00:00:01 ./Plex Media Server
plex 43 36 36 03:48 ? 00:00:02 Plex Plug-in [com.plexapp.system] /usr/lib/plexmediaserv
plex 84 36 4 03:48 ? 00:00:00 /usr/lib/plexmediaserver/Plex DLNA Server
plex 138 36 19 03:48 ? 00:00:00 Plex Plug-in [com.plexapp.agents.fanarttv] /usr/lib/plex
plex 140 36 19 03:48 ? 00:00:00 Plex Plug-in [com.plexapp.agents.htbackdrops] /usr/lib/p
plex 142 36 19 03:48 ? 00:00:00 Plex Plug-in [com.plexapp.agents.lastfm] /usr/lib/plexme
root 202 1 0 03:48 ? 00:00:00 ps -ef
That looks good. As soon as I stop the bash shell, the container will stop. So let’s start the container and set the main process as the script we created (/usr/bin/plex.sh) to start the plex service. Using the init script with a systemd OS was problematic (there are some workarounds but I didn’t go down that path). In the end running the following to start the plex container worked out:
docker run -v /usr/lib/plexmediaserver:/usr/lib/plexmediaserver -v /var/lib/plexmediaserver:/var/lib/plexmediaserver --ulimit memlock=3072000:3072000 --name=plex -it -h plex -d centos-plex /usr/bin/plex.sh
To make sure it’s running:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:02:11]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bfc86fc4ed39 centos-plex "/usr/bin/plex.sh" 33 minutes ago Up 33 minutes plex
and also within the container:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 07:26:14]
└─[0] <> docker exec plex ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 02:30 ? 00:00:00 /bin/bash /usr/bin/plex.sh
root 6 1 0 02:30 ? 00:00:00 su -s /bin/sh elatov -c . /etc/sysconfig/PlexMediaServer; cd /usr/lib/plexmediaserver; ./Plex\ Media\ Server
plex 7 6 0 02:30 ? 00:00:00 sh -c . /etc/sysconfig/PlexMediaServer; cd /usr/lib/plexmediaserver; ./Plex\ Media\ Server
plex 11 7 0 02:30 ? 00:00:00 ./Plex Media Server
plex 18 11 0 02:30 ? 00:00:05 Plex Plug-in [com.plexapp.system] /usr/lib/plexmediaserver/Resources/Plug-ins-f38ac80/Framework.bundle/Contents/Resources/Versions/2/Python/bootstrap.pyc --server-version 0.9.12.19.1537-f38ac80 /usr/lib/plexmediaserver/Resources/Plug-ins-f38ac80/System.bundle
plex 61 11 0 02:30 ? 00:00:00 /usr/lib/plexmediaserver/Plex DLNA Server
root 336 0 0 02:57 ? 00:00:00 ps -ef
And here is the IP within the container:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:04:46]
└─[0] <> docker exec plex ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
78: eth0@if79: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link-netnsid 0
inet 192.168.1.37/24 scope global eth0
valid_lft forever preferred_lft forever
And on the host, I saw the virtual interface attached to the bridge:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:05:42]
└─[0] <> brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c29a3d4fa no ens160
veth907520a
And checking on other media clients I saw the new Plex Server discovered:
┌─[elatov@gen] - [/home/elatov] - [2015-12-31 05:38:51]
└─[0] <> gssdp-discover -i enp0s25 --timeout=3 --target=urn:schemas-upnp-org:device:MediaServer:1
Using network interface enp0s25
Scanning for resources matching urn:schemas-upnp-org:device:MediaServer:1
Showing "available" messages
resource available
USN: uuid:9c675b5f-b102-fda7-fec9-c2e51cbeec5c::urn:schemas-upnp-org:device:MediaServer:1
Location: http://192.168.1.104:80/upnpms/dev
resource available
USN: uuid:ddfb0688-ac14-f8a5-e9c1-3bba365393b6::urn:schemas-upnp-org:device:MediaServer:1
Location: http://192.168.1.37:32469/DeviceDescription.xml
resource available
USN: uuid:61314ed0-059b-fd97-ffff-ffffd7babedf::urn:schemas-upnp-org:device:MediaServer:1
Location: http://192.168.1.100:51307/dev/61314ed0-059b-fd97-ffff-ffffd7babedf/desc
Cleaning up Docker Containers
To stop and remove the container, let’s first stop it:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:02:55]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bfc86fc4ed39 centos-plex "/usr/bin/plex.sh" 36 minutes ago Up 36 minutes plex
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:06:42]
└─[1] <> docker stop plex
plex
and finally let’s remove it:
┌─[elatov@m2] - [/home/elatov] - [2015-12-31 08:10:06]
└─[0] <> docker rm plex
plex
Building Docker Images with a DockerFile
If you want you can also use a DockerFile to help you build the image instead of running the above commands in the image. Here is an example, let’s create a directory with all the appropriate files:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:22:33]
└─[0] <> ls
Dockerfile PlexMediaServer plex.sh
And here is the DockerFile:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:21:30]
└─[0] <> cat Dockerfile
FROM docker.io/centos:latest
COPY plex.sh /usr/bin/
COPY PlexMediaServer /etc/sysconfig/
RUN chmod +x /usr/bin/plex.sh
RUN groupadd -g 1000 plex
RUN useradd -u 1000 -g plex plex
ENTRYPOINT ["/usr/bin/plex.sh"]
Now we can build our new image:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:17:36]
└─[0] <> docker build -t karim/centos-plex:v1 .
Sending build context to Docker daemon 5.632 kB
Step 0 : FROM docker.io/centos:latest
---> 60e65a8e4030
Step 1 : COPY plex.sh /usr/bin/
---> 69d36851df37
Removing intermediate container da470325f34f
Step 2 : COPY PlexMediaServer /etc/sysconfig/
---> 8d64d13329b5
Removing intermediate container 7088c6bdbf07
Step 3 : RUN chmod +x /usr/bin/plex.sh
---> Running in 659f83565e1d
---> 6b5c3681cc39
Removing intermediate container 659f83565e1d
Step 4 : RUN groupadd -g 1000 plex
---> Running in dde8387734c6
---> 4d3f6ce1feae
Removing intermediate container dde8387734c6
Step 5 : RUN useradd -u 1000 -g plex plex
---> Running in c60f00b02c1e
---> d55ce2f7fc9f
Removing intermediate container c60f00b02c1e
Step 6 : ENTRYPOINT /usr/bin/plex.sh
---> Running in 92db7c6d103c
---> 2b0851723ec4
Removing intermediate container 92db7c6d103c
Successfully built 2b0851723ec4
To confirm the image is built we can list out images and see it there:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:18:13]
└─[0] <> docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
karim/centos-plex v1 2b0851723ec4 33 seconds ago 196.6 MB
If you want you can use the inspect option to check more information about the image:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:19:04]
└─[0] <> docker inspect karim/centos-plex:v1
[
{
"Id": "2b0851723ec4981c81e630ef75e35723cc95250e2329522df80f34aba44f1c17",
"Parent": "d55ce2f7fc9f73417121b6057df612f89a19d4c39f5a5b7189febfd6e11c0ea3",
"Comment": "",
"Created": "2016-01-05T03:18:11.122812316Z",
"Container": "92db7c6d103c852e0af4cb00412032462889ab8e0739d9700f4c521d0f0dd51c",
"ContainerConfig": {
"Hostname": "f77e60ad5dfc",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": null,
"PublishService": "",
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ENTRYPOINT \u0026{[\"/usr/bin/plex.sh\"]}"
],
"Image": "d55ce2f7fc9f73417121b6057df612f89a19d4c39f5a5b7189febfd6e11c0ea3",
"Volumes": null,
"VolumeDriver": "",
"WorkingDir": "",
"Entrypoint": [
"/usr/bin/plex.sh"
],
"NetworkDisabled": false,
"MacAddress": "",
"OnBuild": [],
"Labels": {
"build-date": "2015-12-23",
"license": "GPLv2",
"name": "CentOS Base Image",
"vendor": "CentOS"
}
},
"DockerVersion": "1.8.2-el7.centos",
"Author": "",
"Config": {
"Hostname": "f77e60ad5dfc",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": null,
"PublishService": "",
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "d55ce2f7fc9f73417121b6057df612f89a19d4c39f5a5b7189febfd6e11c0ea3",
"Volumes": null,
"VolumeDriver": "",
"WorkingDir": "",
"Entrypoint": [
"/usr/bin/plex.sh"
],
"NetworkDisabled": false,
"MacAddress": "",
"OnBuild": [],
"Labels": {
"build-date": "2015-12-23",
"license": "GPLv2",
└─[1] <>
"name": "CentOS Base Image",
"vendor": "CentOS"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 0,
"VirtualSize": 196640548,
"GraphDriver": {
"Name": "devicemapper",
"Data": {
"DeviceId": "194",
"DeviceName": "docker-253:0-50331734-2b0851723ec4981c81e630ef75e35723cc95250e2329522df80f34aba44f1c17",
"DeviceSize": "107374182400"
}
}
}
]
And then doing a test run:
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:21:06]
└─[1] <> docker run -v /usr/lib/plexmediaserver:/usr/lib/plexmediaserver -v /var/lib/plexmediaserver:/var/lib/plexmediaserver --ulimit memlock=3072000:3072000 -d -it karim/centos-plex:v1
402f54fc78510401f1434212f2c394bfd38b80dffe4a508cd9c8a00761e1b9e1
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:21:11]
└─[0] <> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
402f54fc7851 karim/centos-plex:v1 "/usr/bin/plex.sh" 6 seconds ago Up 5 seconds loving_panini
┌─[elatov@m2] - [/home/elatov/docker] - [2016-01-04 08:21:16]
└─[0] <> docker exec loving_panini ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:21 ? 00:00:00 /bin/bash /usr/bin/plex.sh
root 6 1 0 03:21 ? 00:00:00 su -s /bin/sh plex -c . /etc/sysconfig/PlexMediaServer; cd /usr/lib/plexmediaserver; ./Plex\ Media\ Server
plex 7 6 0 03:21 ? 00:00:00 sh -c . /etc/sysconfig/PlexMediaServer; cd /usr/lib/plexmediaserver; ./Plex\ Media\ Server
plex 11 7 28 03:21 ? 00:00:05 ./Plex Media Server
root 430 0 0 03:21 ? 00:00:00 ps -ef
When working with DockerFiles it’s important to know the difference between CMD and ENTRYPOINT directives. Here are some good links that talk about that:
I ended up using ENTRYPOINT but I could’ve used CMD in my case as well. I will admit this is not the best way to run plex in a container, but there are great examples that cover appropriate use cases: