Docker compose plex

Docker compose plex DEFAULT

Related Posts

Late last year, I bought a Blu-ray/DVD drive for my home computer and ripped all the movies and television shows I have on physical disks. The files are now stored on the NAS running in my local network. I can watch that media on just about any device in my house using Plex, a wonderful piece of software for streaming media around the network.

Today I’ll explain how I set up my system to run Plex’s software via the Plex image on a Docker host in my basement.

Want to learn more about my home network? Last time I wrote about running a Unifi Controller image.

About describes their organization as:

A group of like-minded enthusiasts from across the world who build and maintain the largest collection of Docker images on the web. At our core are the principles behind Free and Open Source Software. Our primary goal is to provide easy-to-use and streamlined Docker images with clear and concise documentation.

I’ve been using images for a couple of years; they are certainly easy-to-use, clear, and concisely documented. I tend to check here first when I need a new image.

Plex Container Configuration

I tend to use to build and run my images and containers. Here are the contents of the for this project:

Much of this is derived from the instructions in the image’s README file:

Let’s step through some of the interesting bits.


My personal preference is to lock images down to a specific version, if at all feasible. This way I won’t be surprised when, say, a new version of an image requires or breaks the current configuration. LinuxServer is great about providing versioned images over time.

Personally, I rarely update the Plex image. I don’t use it that often, so new features are not particularly compelling to me.


Here I make the Intel QuickSync device available to the container. It’s used for hardware transcoding. The README’s Hardware Acceleration section has more information.


LinuxServer has a great system for setting user and group permissions. In this case, I have and set to the user and group number on my host system. (I have the comment there so that, when I look at this file again three months later, I can remember why I have some hardcoded numbers typed into the file.)


These ports are recommended by the image’s README file. The README and comments document what all of them are for. In my case, I’m running in more, and two of the port mappings are commented out because they were conflicting with something else on my system. I avoided the problem by not using those mappings, and everything is working well enough in my home. Your mileage may vary. Check the README for more information.


Last are my volume mappings. Two things of note:

  • I map the two directories read-only to provide a little extra protection if something goes wrong.
  • I have the directory mapped separately from the directory so that it’s easier to back up one without the other.

Getting a Little Trickier

This configuration is a smidge more sophisticated than the Unifi Controller configuration I wrote about last time. It’s got a device mapping, a different kind of networking, and some trial-and-error port configuration. But it’s hopefully still not too bad. I look forward to future posts with even more sophisticated setups.


Official Docker container for Plex Media Server

With our easy-to-install Plex Media Server software and your Plex apps, available on all your favorite phones, tablets, streaming devices, gaming consoles, and smart TVs, you can stream your video, music, and photo collections any time, anywhere, to any device.


Before you create your container, you must decide on the type of networking you wish to use. There are essentially three types of networking available:

  • (default)

The networking creates an entirely new network within the host and runs containers within there. This network is connected to the physical network via an internal router and docker configures this router to forward certain ports through to the containers within. The networking uses the IP address of the host running docker such that a container's networking appears to be the host rather than separate. The networking creates a new virtual computer on the network which is the container. For purposes of setting up a plex container, the and are very similar in configuration.

Using or is the easier of the three setups and has the fewest issues that need to be worked around. However, some setups may be restricted to only running in the mode. Plex can be made to work in this mode, but it is more complicated.

For those who use docker-compose, this repository provides the necessary YML template files to be modified for your own use.

Host Networking

Note: If your file is missing an entry for , you should add one before using host networking.

Macvlan Networking

Similar to above with these changes:

  • The network has been changed to which is the name of the network (yours is likely to be different).
  • The parameter has been added to specify the IP address of the container. This parameter is optional since the network may specify IPs to use but this parameter overrides those settings.
  • The has been added since this networking type doesn't use the hostname of the host.

Bridge Networking

Note: In this configuration, you must do some additional configuration:

  • If you wish your Plex Media Server to be accessible outside of your home network, you must manually setup port forwarding on your router to forward to the specified above. By default you can forward port 32400, but if you choose to use a different external port, be sure you configure this in Plex Media Server's settings. With this type of docker networking, the Plex Media Server is essentially behind two routers and it cannot automatically setup port forwarding on its own.
  • (Plex Pass only) After the server has been set up, you should configure the preference to contain the network of your LAN. This instructs the Plex Media Server to treat these IP addresses as part of your LAN when applying bandwidth controls. The syntax is the same as the below. For example will allow access to the entire range and the range.

Using on ARM devices

The provided templates use the image which is the amd64 build and won't work on ARM devices.

To use with ARM devices, you must first build one of the ARM images locally.

docker build -t plexinc/pms-docker:latest -f Dockerfile.armv7 .# or arm64

Then you can .


  • Forwards port 32400 from the host to the container. This is the primary port that Plex uses for communication and is required for Plex Media Server to operate.
  • Forwards complete set of other ports used by Plex to the container. For a full explanation of which you may need, please see the help article:
  • The path where you wish Plex Media Server to store its configuration data. This database can grow to be quite large depending on the size of your media collection. This is usually a few GB but for large libraries or libraries where index files are generated, this can easily hit the 100s of GBs. If you have an existing database directory see the section below on the directory setup. Note: the underlying filesystem needs to support file locking. This is known to not be default enabled on remote filesystems like NFS, SMB, and many many others. The 9PFS filesystem used by FreeNAS Corral is known to work but the vast majority will result in database corruption. Use a network share at your own risk.
  • The path where you would like Plex Media Server to store its transcoder temp files. If not provided, the storage space within the container will be used. Expect sizes in the 10s of GB.
  • This is provided as examples for providing media into the container. The exact structure of how the media is organized and presented inside the container is a matter of user preference. You can use as many or as few of these parameters as required to provide your media to the container.
  • These are environment variables which configure the container. See below for a description of their meanings.

The following are the recommended parameters. Each of the following parameters to the container are treated as first-run parameters only. That is, all other parameters are ignored on subsequent runs of the server. We recommend that you set the following parameters:

  • HOSTNAME Sets the hostname inside the docker container. For example will set the servername to . Not needed in Host Networking.
  • TZ Set the timezone inside the container. For example: . The complete list can be found here:
  • PLEX_CLAIM The claim token for the server to obtain a real server token. If not provided, server will not be automatically logged in. If server is already logged in, this parameter is ignored. You can obtain a claim token to login your server to your plex account by visiting
  • ADVERTISE_IP This variable defines the additional IPs on which the server may be found. For example: . This adds to the list where the server advertises that it can be found. This is only needed in Bridge Networking.

These parameters are usually not required but some special setups may benefit from their use. As in the previous section, each is treated as first-run parameters only:

  • PLEX_UID The user id of the user created inside the container.
  • PLEX_GID The group id of the group created inside the container
  • CHANGE_CONFIG_DIR_OWNERSHIP Change ownership of config directory to the plex user. Defaults to . If you are certain permissions are already set such that the user within the container can read/write data in it's config directory, you can set this to to speed up the first run of the container.
  • ALLOWED_NETWORKS IP/netmask entries which allow access to the server without requiring authorization. We recommend you set this only if you do not sign in your server. For example will allow access to the entire range and the range. Note: If you are using Bridge networking, then localhost will appear to plex as coming from the docker networking gateway which is often .


Permissions of mounted media outside the container do apply to the Plex Media Server running within the container. As stated above, the Plex Media Server runs as a specially created user within the container. This user may not exist outside the container and so the and parameters are used to set the user id and group id of this user within the container. If you wish for the Plex Media Server to run under the same permissions as your own user, execute the following to find out these ids:

You'll see a line like the following:

In the above case, if you set the and to , then the permissions will match that of your own user.


In addition to the standard version and tags, two other tags exist: and . These two images behave differently than your typical containers. These two images do not have any Plex Media Server binary installed. Instead, when these containers are run, they will perform an update check and fetch the latest version, install it, and then continue execution. They also run the update check whenever the container is restarted. To update the version in the container, simply stop the container and start container again when you have a network connection. The startup script will automatically fetch the appropriate version and install it before starting the Plex Media Server.

The restricts this check to public versions only where as will fetch beta versions. If the server is not logged in or you do not have Plex Pass on your account, the tagged images will be restricted to publicly available versions only.

To view the Docker images head over to

Config Directory

Inside the docker container, the database is stored with a in the directory.

If you wish to migrate an existing directory to the docker config directory:

  • Locate the current config directory as directed here:
  • If the config dir is stored in a location such as , the config dir will be .
  • If the config dir does not contain or the directory containing has data unrelated to Plex, such as OS X, then you should:
    • Create a new directory which will be your new config dir.
    • Within that config dir, create the directories
    • Copy into that
  • Note: by default Plex will claim ownership of the entire contents of the dir (see CHANGE_CONFIG_DIR_OWNERSHIP for more information). As such, there should be nothing in that dir that you do not wish for Plex to own.

Useful information

  • Start the container:
  • Stop the container:
  • Shell access to the container while it is running:
  • See the logs given by the startup script in real time:
  • Restart the application and upgrade to the latest version:

Fedora, CentOS, Red Hat

If you get the following output after you have started the container, then this is due to a patched version of Docker (#158)

As a workaround you can add to volumes in your docker-compose.yml or to the docker create command.

Intel Quick Sync Hardware Transcoding Support

If your Docker host has access to a supported CPU with the Intel Quick Sync feature set and you are a current Plex Pass subscriber, you can enable hardware transcoding within your Plex Docker container.

A list of current and previous Intel CPU's supporting Quick Sync is available on the Intel website.

Hardware transcoding is a Plex Pass feature that can be added to your Docker container by bind mounting the relevant kernel device to the container. To confirm your host kernel supports the Intel Quick Sync feature, the following command can be executed on the host:

which should output if Quick Sync is available. To pass the kernel device through to the container, add the device parameter like so:

In the example above, the was added to the command to pass through the kernel device. Once the Plex Media Server container is running, the following steps will turn on the Hardware Transcoding option:

  1. Open the Plex Web app.
  2. Navigate to Settings > Server > Transcoder to access the server settings.
  3. Turn on Show Advanced in the upper-right corner to expose advanced settings.
  4. Turn on Use hardware acceleration when available.
  5. Click Save Changes at the bottom.

NOTE: Intel Quick Sync support also requires newer 64-bit versions of the Ubuntu or Fedora Linux operating system to make use of this feature. If your Docker host also has a dedicated graphics card, the video encoding acceleration of Intel Quick Sync Video may become unavailable when the GPU is in use. If your computer has an NVIDIA GPU, please install the latest Latest NVIDIA drivers for Linux to make sure that Plex can use your NVIDIA graphics card for video encoding (only) when Intel Quick Sync Video becomes unavailable._

Your mileage may vary when enabling hardware transcoding as newer generations of Intel CPU's provide transcoding of higher resolution video and newer codecs. There is a useful Wikipedia page here which provides a handy matrix for each CPU generation's support of on-chip video decoding.

Windows (Not Recommended)

Docker on Windows works differently than it does on Linux; it uses a VM to run a stripped-down Linux and then runs docker within that. The volume mounts are exposed to the docker in this VM via SMB mounts. While this is fine for media, it is unacceptable for the directory because SMB does not support file locking. This will eventually corrupt your database which can lead to slow behavior and crashes. If you must run in docker on Windows, you should put the directory mount inside the VM and not on the Windows host. It's worth noting that this warning also extends to other containers which use SQLite databases.

Running on a headless server with container using host networking

If the claim token is not added during initial configuration you will need to use ssh tunneling to gain access and setup the server for first run. During first run you setup the server to make it available and configurable. However, this setup option will only be triggered if you access it over http://localhost:32400/web, it will not be triggered if you access it over http://ip_of_server:32400/web. If you are setting up PMS on a headless server, you can use a SSH tunnel to link http://localhost:32400/web (on your current computer) to http://localhost:32400/web (on the headless server running PMS):

  1. Surge transportation chicago
  2. 2005 f150 ignition switch
  3. Golden age 251
  4. Wire mesh file organizer

Building an automated Plex stack using Docker Compose

I regularly help people install, configure, and run automated Plex stacks. I have found that unfortunately I spend a lot of time solving the infrastructure stuff before we can even get to the application configs. The various mainstream containers aren’t setup for hot linking, Spaceinvader One has a video that has a dated screenshot in it (not a complaint! he’s awesome!), etc. All things that beginners stumble over. In an attempt to make that first part easy, I created the following.


  • Torrents and Usenet downloads are wrapped with a VPN, and I use PIA. If you use something else, you’ll want to tweak things as described here. Regardless, even if you use PIA, you need to get the opvn files and add them to the correct directory. The link provided goes into detail. Note that only torrents require port forwarding.

  • You are using a filesystem structure that allows for hot linking. I’ve described a good way to do that here, in the event you need to move your stuff around.

  • This setup is built to run on Windows because that’s where I find most beginners are doing their builds. Adopting it to Mac/Linux is not complicated.

  • Docker’s root directory will be C:\Users<win_username>\Docker. This too is easy to change using the .env file

  • I have not added SWAG/LetsEncrypt because most beginners don’t own domains. I’ve primed the setup though using a custom Docker network that makes adding SWAG easy.

Bonus: put the text below into a decent text editor and collapse the services section


version: '3.9' networks: docker_internal_network: name: ${DOCKER_NETWORK_NAME} services: plex: ######### [http://localhost:32400/web/ container_name: ${DOCKER_CONTAINER_PREFIX}_jackett environment: - PUID=1000 - PGID=1000 - TZ=${DOCKER_TIME_ZONE} volumes: - ${DOCKER_APPDATA_PATH}\jackett:/config - ${DATA_PATH}:/data ports: - '9117:9117' restart: unless-stopped deluge-vpn: ### [http://localhost:8112] Delude VPN + Privoxy - torrent downloader, wrapped in a VPN, also running Privoxy [8118] image: binhex/arch-delugevpn container_name: ${DOCKER_CONTAINER_PREFIX}_deluge-vpn cap_add: - NET_ADMIN environment: - VPN_ENABLED=yes - VPN_USER=${VPN_USERNAME} - VPN_PASS=${VPN_PASSWORD} - VPN_PROV=pia - VPN_CLIENT=openvpn # connection files located at - STRICT_PORT_FORWARD=yes - ENABLE_PRIVOXY=no - LAN_NETWORK=${VPN_LAN_SUBNET} - NAME_SERVERS=,,,,,,, - DELUGE_DAEMON_LOG_LEVEL=error - DELUGE_WEB_LOG_LEVEL=error #- VPN_INPUT_PORTS=1234 #- VPN_OUTPUT_PORTS=5678 - DEBUG=false - PUID=1000 - PGID=1000 - TZ=${DOCKER_TIME_ZONE} volumes: - '/etc/localtime:/etc/localtime:ro' - ${DOCKER_APPDATA_PATH}\deluge-vpn:/config - ${DATA_PATH}:/data ports: - '8112:8112' - '8118:8118' - '58846:58846' - '58946:58946' restart: unless-stopped sabnzbd-vpn: ## [http://localhost:8080] SABnzbd VPN - usenet downloader, wrapped in a VPN image: binhex/arch-sabnzbdvpn container_name: ${DOCKER_CONTAINER_PREFIX}_sabnzbd-vpn cap_add: - NET_ADMIN environment: - VPN_ENABLED=yes - VPN_USER=${VPN_USERNAME} - VPN_PASS=${VPN_PASSWORD} - VPN_PROV=pia - VPN_CLIENT=openvpn # connection files located at - STRICT_PORT_FORWARD=no - ENABLE_PRIVOXY=no - LAN_NETWORK=${VPN_LAN_SUBNET} - NAME_SERVERS=,,,,,,, #- VPN_INPUT_PORTS=1234 #- VPN_OUTPUT_PORTS=5678 - DEBUG=false - PUID=1000 - PGID=1000 - TZ=${DOCKER_TIME_ZONE} volumes: - /etc/localtime:/etc/localtime:ro - ${DOCKER_APPDATA_PATH}\sabnzbd-vpn:/config - ${DATA_PATH}:/data ports: - '8080:8080' - '8090:8090' #- '8118:8118' # disabled because privoxy is running in the torrent container restart: unless-stopped gaps: ######### [http://localhost:8484] GAPS - identifies movie collections and missing films container_name: ${DOCKER_CONTAINER_PREFIX}_gaps environment: - PUID=1000 - PGID=1000 - TZ=${DOCKER_TIME_ZONE} volumes: - ${DOCKER_APPDATA_PATH}\gaps:/config ports: - '8484:8484' restart: unless-stopped dozzle: ####### [http://localhost:9999] Dozzle - Docker log reader image: amir20/dozzle:latest container_name: ${DOCKER_CONTAINER_PREFIX}_dozzle volumes: - /var/run/docker.sock:/var/run/docker.sock ports: - '9999:8080' restart: unless-stopped


# Docker DOCKER_NETWORK_NAME = swag DOCKER_CONTAINER_PREFIX = media-server-stack DOCKER_TIME_ZONE = America/Los_Angeles DOCKER_APPDATA_PATH = C:\Users\Jesse\Docker\appdata # Top-Level Location of Your Media and Incoming Data DATA_PATH = Z:\ # Plex PLEX_CLAIM = PLEX_ADVERTISE_IP = http://localhost:32400/ PLEX_TRANSCODE_PATH = C:\Users\Jesse\Docker\transcode # VPN VPN_USERNAME = p####### VPN_PASSWORD = ???????????????????? VPN_LAN_SUBNET =

For those new to Docker Compose, using these two files looks like this:

C:\Users\Jesse\Docker>docker ps --format "table {{.Names}}\t| {{.State}}\t| {{.Status}}" NAMES | STATE | STATUS C:\Users\Jesse\Docker>docker-compose up -d Creating network "swag" with the default driver Creating network "docker_default" with the default driver Creating media-server-stack_plex ... done Creating media-server-stack_dozzle ... done Creating media-server-stack_sabnzbd-vpn ... done Creating media-server-stack_lidarr ... done Creating media-server-stack_deluge-vpn ... done Creating media-server-stack_radarr ... done Creating media-server-stack_ombi ... done Creating media-server-stack_gaps ... done Creating media-server-stack_jackett ... done Creating media-server-stack_sonarr ... done Creating media-server-stack_tautulli ... done Creating media-server-stack_nzbhydra2 ... done Creating media-server-stack_bazarr ... done C:\Users\Jesse\Docker>docker ps --format "table {{.Names}}\t| {{.State}}\t| {{.Status}}" NAMES | STATE | STATUS media-server-stack_tautulli | running | Up 7 minutes media-server-stack_sonarr | running | Up 7 minutes media-server-stack_bazarr | running | Up 7 minutes media-server-stack_radarr | running | Up 7 minutes media-server-stack_nzbhydra2 | running | Up 7 minutes media-server-stack_deluge-vpn | running | Up 7 minutes media-server-stack_jackett | running | Up 7 minutes media-server-stack_gaps | running | Up 7 minutes media-server-stack_lidarr | running | Up 7 minutes media-server-stack_sabnzbd-vpn | running | Up 7 minutes media-server-stack_ombi | running | Up 7 minutes media-server-stack_dozzle | running | Up 7 minutes media-server-stack_plex | running | Up 7 minutes (healthy) C:\Users\Jesse\Docker>
This should have all of your apps running and ready for configuration.


Cómo instalar Plex usando Docker-compose

Running a Plex Media Server with Docker Compose

So recently I have been using docker extensively at work, primarily for setting up/improving a local dev environment, as well as running some containers on AWS ECS.

To be honest, I initially didn’t quite understand what docker was used for. I mean, “containers”? Why not just use a VM? But once it really clicked in my head, whoa, containers. They’re awesome.

If I had to distill what I discovered about docker into a few key points, it would be the following:

  1. It lets you create isolated environments (aka containers), each with it’s own set of dependencies (aka no more conflicting dependencies!)
  2. You can configure these environments as a document, and then share these documents with others.
  3. Given these documents, you can easily and reliably reproduce these environments
  4. You don’t need to manually install dependencies, etc. docker handles that for you!
  5. Unlike a VM, docker containers are NOT using virtualized hardware, etc. Docker uses cgroups and namespaces to isolate the environments from each other, but they are still directly issuing calls to the host linux kernel. This means containers are more like programs; they spin up fast, are cheap to stop and start, and don’t incur the performance overhead of running a virtual machine

This enables some pretty powerful behavior.

For example, I can spin up a vanilla linux server with a fresh OS install. Once you install docker on it, you can then feed docker some dockerfiles, it can then use those dockerfiles to spin up a bunch of isolated environments (such as Postgresql database, a rails web server, a plex server, pretty much anything with a dockerfile).

Each environment will have their own isolated dependencies, and you can even set up networking, port forwarding, etc, between the host machine and these environments! And this is portable to any other linux machine, since all you need on other machines is docker and whatever dockerfiles you used before.

Since docker makes setting up an environment both extremely simple and reproduceable, it seemed like a perfect tool to setup a Plex server.

Lo and behold, plex already has an official docker image, which should theoretically make it extremely easy to setup a plex server.

Unfortunately, Plex inc doesn’t officially provide a config file, which would have made it even easier to setup the server. It would have been as simple as installing docker, downloading the repo, and running the command in terminal. Alas, some manual config is still needed.

The final docker-compose.yml file I came up with is:

Seems simple enough, let’s explain each part:

These should be fairly obvious, these specify where to get the docker image from, and to restart the container unless you manually issue it a stop command.

These are environment variables that are passed into the plex server once you spin it up. The CLAIM token is provided on the plex website, which you’ll need to setup the server.

This part is related to how docker handles networking. If you specify , docker will use ports on the host machine, and map them to to the running container’s ports.

Now you may be thinking that this can be pretty dangerous. I mean, naively mapping all ports that the container uses to the same ports on the host? Sounds like it can be trouble.

Docker actually provides a neat feature related to this, where you can essentially declare an isolated network that is independent of your local host machine. The docker container will expose it’s ports to the local network, and are NOT mapped to the ports on the host machine unless you explicitly provide a mapping. So if the was configured to use a network that, in this example, we’ll call , it would look something like this:

And finally, the last part:

the is exactly what it sounds like: the location where you want the container to save stuff to. To be more specific, this is something called a bind mount, where a directory on your local host machine is bound to the target directory inside the container. Since you want to be able to reliably add/remove media to your plex server, you need to decide on which directory you want to mount into the container.

if this looks confusing to you, think of it this way:

plex expects media to be saved in the directory in the container, so you need to map some directory on your own machine to that directory in the container.

So after all that, the end result is that you can run in terminal, and it’ll do the following:

  • download all dependencies needed for your plex server
  • inject whatever environment variables you specified
  • hook up the container ports to your host machine
  • map file volumes between the host and container
  • and spin up a fully working, live plex server!

Compose plex docker


Plex Media Server Setup in Docker with Network Shares


You will also like:


777 778 779 780 781