Media Servers guide

Plex Docker Compose Setup: Preserve Metadata and Hardware Transcoding

Deploy Plex with durable metadata, deliberate networking, optional hardware transcoding, and a tested backup and rollback path.

Published and reviewed by OpenAlt · September 28, 2026

Smart TV displaying streaming content in modern living room setting with exposed brick wall.
Photo by www.kaboompics.com on Pexels

A safe plex docker compose deployment keeps Plex configuration and its database persistent, mounts the media library separately, and treats hardware transcoding as optional. The container is replaceable; the irreplaceable assets are your Plex database, metadata, preferences, and lawful personal media.

Use a persistent /config, a disposable /transcode directory on fast local storage, and a read-only media mount where practical. Back up Plex configuration independently from the media files.

For related OpenAlt guidance, see Plex alternatives, the Jellyfin deployment guide, and the media streaming category.

Table of Contents

Host prerequisites

Prepare a Linux host with Docker Engine and the Docker Compose plugin. Provide stable storage for Plex configuration and media, plus enough CPU and memory for expected concurrent streams.

Use local SSD storage for /transcode when possible. Transcoding can create large temporary files, while Direct Play may use little or no transcode space. Do not place the Plex database on unreliable removable storage or a network share unless you understand the performance and file-locking implications.

Your host should also have:

  • A fixed or reserved LAN address.
  • Sufficient free filesystem space.
  • Correct time-zone configuration.
  • Firewall rules permitting local Plex access.
  • Optional GPU or integrated graphics support for hardware transcoding.

The official Plex Docker image repository documents supported mounts and host-network or bridge-network deployment choices.

Directory and UID/GID plan

A simple layout separates application data from media:

/srv/plex/config       Plex database, metadata, preferences, and plugins
/srv/plex/transcode    Temporary transcoding files
/srv/media             Movies, shows, music, and other lawful personal media

The /config directory is the critical asset. It contains library organization, posters, watch states, playlists, preferences, and the Plex database.

Choose one ownership policy and apply it consistently. Numeric UID/GID values matter more than usernames. Plex must be able to read and write /config and /transcode; it typically needs only read access to /media.

Before starting Plex, inspect ownership with id, stat, or your file manager. With NFS, SMB, rootless Docker, or a NAS, confirm that the numeric identity presented to the container matches the mounted-directory permissions.

Avoid forcing a Compose user: setting until you have confirmed that the selected image tag supports it. An incorrect permission plan can stop Plex from creating its database or writing transcode files.

Complete Docker Compose example

Replace the sample values before deployment. The media mount is read-only to reduce accidental changes:

services:
  plex:
    image: plexinc/pms-docker:YOUR_VERIFIED_SERVER_TAG
    container_name: plex
    restart: unless-stopped

    environment:
      TZ: YOUR_TIME_ZONE
      PLEX_CLAIM: YOUR_PLEX_CLAIM_TOKEN

    volumes:
      - /srv/plex/config:/config
      - /srv/plex/transcode:/transcode
      - /srv/media:/media:ro

    ports:
      - "32400:32400/tcp"

The bridge-network example is explicit and easy to inspect. Host networking can simplify local discovery, but exposes the container more directly to the host network.

Network modeAdvantageTrade-off
BridgeExplicit ports and isolationRouter forwarding is required
HostOften simpler discoveryLess network isolation

Choose one model deliberately. For production, use a verified Plex server image tag instead of relying indefinitely on latest. Do not confuse an unrelated repository release, such as a Helm chart version, with a Plex Media Server version. The official image documentation is authoritative for image configuration.

First boot and claim-token handling

Create the directories, confirm ownership, and validate Compose before starting:

docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=100 plex

Open Plex Web from the local network, normally through port 32400, and complete initial setup. The claim token associates the new server with your Plex account. Generate it immediately before first boot because it is short-lived.

Never publish a claim token in documentation, screenshots, shell history, issue reports, or shared logs. After the server is claimed, remove PLEX_CLAIM from Compose or your secret store and recreate the container if necessary.

If the server does not appear in your account, check logs, DNS, firewall rules, the host clock, and whether the token expired.

Detailed view of a server rack with a focus on technology and data storage.
Photo by panumas nikhomkhai on Pexels
Detailed image of illuminated server racks showcasing modern technology infrastructure.
Photo by panumas nikhomkhai on Pexels

Hardware device mapping

Start with software transcoding unless the host hardware path is already known to work. Direct play is preferable when the client supports the file and audio format because it avoids unnecessary CPU or GPU work.

For compatible Intel or AMD Linux graphics, an optional mapping may look like this:

    devices:
      - /dev/dri:/dev/dri

Add it only after confirming that /dev/dri exists and the Plex process can use it. NVIDIA hardware generally requires the NVIDIA Container Toolkit and compatible driver/runtime configuration; /dev/dri is not a universal NVIDIA solution.

Enable hardware acceleration in Plex only after the container can see the device. Confirm operation in the Plex dashboard by opening the active session and checking whether it reports Direct Play, Direct Stream, or Transcode. A hardware transcode should identify the hardware path rather than showing CPU-only processing.

Hardware transcoding is host-specific. Driver or kernel changes can break a previously working setup. Check the official Plex Docker repository for image-specific device guidance.

Remote access

Remote access requires more than a running container. Enable Remote Access in Plex and let the server test external connectivity. With bridge networking, forward TCP port 32400 from the router to the Docker host and keep the Compose mapping aligned.

Double NAT, carrier-grade NAT, blocked inbound traffic, changing public IP addresses, and restrictive routers can prevent a direct connection. A green status indicator does not guarantee that every remote client will receive a direct stream.

Use the official Plex remote access guide for current connectivity details. Do not expose unrelated Docker services or administrative ports. Keep the host patched, use strong account security, and test from outside your home LAN.

Backup and restore

Back up /srv/plex/config separately from the media library. This protects the Plex database, metadata, watch history, settings, and library definitions; it does not preserve video, music, image, subtitle, or artwork files stored elsewhere.

Stop Plex before a file-level backup:

docker compose stop plex
tar -C /srv/plex -czf plex-config-backup.tar.gz config
docker compose start plex

Store the archive on separate storage and periodically verify that it can be read. Maintain a separate backup plan for media, including enough capacity for the original files.

To restore, stop Plex, extract the configuration into the expected /config directory, verify ownership, and start the service:

docker compose stop plex
tar -C /srv/plex -xzf plex-config-backup.tar.gz
docker compose start plex

Keep the existing configuration directory available until the restored server has been verified. This preserves a recovery path if the archive or permissions are incorrect.

Upgrade and rollback

Before upgrading, back up /config and record the current image tag:

docker compose pull plex
docker compose up -d plex
docker compose ps
docker compose logs --tail=100 plex

Test playback, library scans, remote access, and hardware transcoding after the upgrade. Keep the previous known-good tag available.

If the new image fails, restore the previous verified tag and recreate the service:

docker compose up -d plex

A database migrated by a newer Plex version may not work safely with an older version. If rollback requires database restoration, stop Plex first and restore the matching configuration backup.

Troubleshooting

If Plex repeatedly restarts, inspect docker compose ps and recent logs. /config or /transcode permission errors usually indicate incorrect ownership, an incompatible UID/GID plan, or a read-only mount.

If media is missing, confirm that the host path exists, the container path is /media, and the Plex library points to /media rather than the host path. Verify that the container can read the mount.

If playback buffers, inspect the dashboard session. Direct Play, Direct Stream, and Transcode have different resource requirements; software transcoding can saturate the CPU.

If hardware transcoding is absent, verify the device, permissions, drivers, Plex settings, and any required account features. Remove the device mapping temporarily if it prevents startup.

If remote access fails, test local playback first, then check firewall rules, router forwarding, double NAT, CGNAT, and the external port test.

Frequently asked questions

Is the Plex container itself important to back up?

No. Recreate it from Compose and the image tag. Back up /config, which contains the database, metadata, preferences, and library state.

Should the media mount be read-only?

Usually. Plex generally needs to read media for scanning and playback. Use read-write access only for a specific, understood workflow.

Do I need hardware transcoding?

No. Direct play may avoid transcoding, and software transcoding can be sufficient for a small household. Hardware transcoding depends on compatible hardware, drivers, permissions, Plex settings, and client formats.

Can I use latest for upgrades?

You can, but a verified, pinned Plex server tag is more predictable. Back up /config, record the current tag, and do not interpret unrelated repository release tags as Plex server versions.