
Advanced Plex Configuration on Linux
Advanced Plex Configuration on Linux
Elevate your Plex server with advanced Linux configurations, Docker deployments, and automation.
Docker Deployment
Basic Docker Setup
# Pull official Plex image
docker pull plexinc/pms-docker
# Run Plex container
docker run -d \
--name plex \
--network=host \
-e TZ="America/New_York" \
-e PLEX_CLAIM="claim-xxxxxxxxxxxx" \
-v /path/to/config:/config \
-v /path/to/transcode:/transcode \
-v /path/to/media:/data \
plexinc/pms-dockerDocker Compose
Create docker-compose.yml:
version: '3.8'
services:
plex:
image: plexinc/pms-docker:latest
container_name: plex
restart: unless-stopped
network_mode: host
environment:
- TZ=America/New_York
- PLEX_CLAIM=claim-xxxxxxxxxxxx
- PLEX_UID=1000
- PLEX_GID=1000
volumes:
- ./config:/config
- ./transcode:/transcode
- /mnt/media/movies:/data/movies
- /mnt/media/tv:/data/tv
- /mnt/media/music:/data/music
devices:
- /dev/dri:/dev/dri # Intel Quick Sync# Start with Docker Compose
docker compose up -d
# View logs
docker compose logs -f plex
# Update Plex
docker compose pull && docker compose up -dHardware Transcoding in Docker
# NVIDIA GPU
services:
plex:
# ... other config ...
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
# Intel Quick Sync
services:
plex:
# ... other config ...
devices:
- /dev/dri:/dev/driSystemd Service Management
Custom Systemd Service
sudo nano /etc/systemd/system/plexmediaserver.service[Unit]
Description=Plex Media Server
After=network-online.target
[Service]
Type=simple
User=plex
Group=plex
ExecStartPre=/bin/sleep 10
ExecStart=/usr/lib/plexmediaserver/Plex\ Media\ Server
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=5
Environment="PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application Support"
Environment="PLEX_MEDIA_SERVER_HOME=/usr/lib/plexmediaserver"
Environment="PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS=6"
Environment="PLEX_MEDIA_SERVER_INFO_DEVICE=PC"
Environment="PLEX_MEDIA_SERVER_INFO_VENDOR=Linux"
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable plexmediaserver
sudo systemctl start plexmediaserverService Management Commands
# Status and control
sudo systemctl status plexmediaserver
sudo systemctl restart plexmediaserver
sudo systemctl stop plexmediaserver
# View logs
sudo journalctl -u plexmediaserver -f
sudo journalctl -u plexmediaserver --since "1 hour ago"Database Management
Locate Database
# Default locations
ls -la "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/"
# Docker location
ls -la /path/to/config/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/Backup Script
#!/bin/bash
# /usr/local/bin/plex-backup.sh
PLEX_DB="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases"
BACKUP_DIR="/backup/plex"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Stop Plex for clean backup
sudo systemctl stop plexmediaserver
sleep 5
# Backup database
cp "$PLEX_DB/com.plexapp.plugins.library.db" "$BACKUP_DIR/library_$DATE.db"
cp "$PLEX_DB/com.plexapp.plugins.library.blobs.db" "$BACKUP_DIR/blobs_$DATE.db"
# Backup preferences
cp "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml" "$BACKUP_DIR/Preferences_$DATE.xml"
# Start Plex
sudo systemctl start plexmediaserver
# Compress backups
tar -czf "$BACKUP_DIR/plex_backup_$DATE.tar.gz" -C "$BACKUP_DIR" \
"library_$DATE.db" "blobs_$DATE.db" "Preferences_$DATE.xml"
# Remove uncompressed files
rm "$BACKUP_DIR/library_$DATE.db" "$BACKUP_DIR/blobs_$DATE.db" "$BACKUP_DIR/Preferences_$DATE.xml"
# Remove old backups
find "$BACKUP_DIR" -name "plex_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $BACKUP_DIR/plex_backup_$DATE.tar.gz"Database Optimization
#!/bin/bash
# /usr/local/bin/plex-optimize.sh
PLEX_DB="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases"
# Stop Plex
sudo systemctl stop plexmediaserver
sleep 5
# Optimize main database
sqlite3 "$PLEX_DB/com.plexapp.plugins.library.db" "VACUUM;"
sqlite3 "$PLEX_DB/com.plexapp.plugins.library.db" "REINDEX;"
# Optimize blobs database
sqlite3 "$PLEX_DB/com.plexapp.plugins.library.blobs.db" "VACUUM;"
# Start Plex
sudo systemctl start plexmediaserver
echo "Database optimization completed"Automation with Scripts
Library Scan Script
#!/bin/bash
# /usr/local/bin/plex-scan.sh
PLEX_URL="http://localhost:32400"
PLEX_TOKEN="your-token-here"
# Scan all libraries
curl -s "$PLEX_URL/library/sections/all/refresh?X-Plex-Token=$PLEX_TOKEN"
# Or scan specific library (get section ID from API)
# curl -s "$PLEX_URL/library/sections/1/refresh?X-Plex-Token=$PLEX_TOKEN"Cron Jobs
# Edit crontab
crontab -e# Daily library scan at 4 AM
0 4 * * * /usr/local/bin/plex-scan.sh >> /var/log/plex-scan.log 2>&1
# Weekly backup at 3 AM Sunday
0 3 * * 0 /usr/local/bin/plex-backup.sh >> /var/log/plex-backup.log 2>&1
# Monthly database optimization at 2 AM, 1st of month
0 2 1 * * /usr/local/bin/plex-optimize.sh >> /var/log/plex-optimize.log 2>&1Tautulli Monitoring
Docker Installation
# Add to docker-compose.yml
tautulli:
image: tautulli/tautulli:latest
container_name: tautulli
restart: unless-stopped
ports:
- "8181:8181"
environment:
- TZ=America/New_York
- PUID=1000
- PGID=1000
volumes:
- ./tautulli:/configNative Installation
# Install dependencies
sudo apt install python3 python3-pip git
# Clone Tautulli
git clone https://github.com/Tautulli/Tautulli.git /opt/tautulli
# Create service
sudo nano /etc/systemd/system/tautulli.service[Unit]
Description=Tautulli
After=network.target
[Service]
Type=simple
User=plex
ExecStart=/usr/bin/python3 /opt/tautulli/Tautulli.py --datadir /opt/tautulli
Restart=on-failure
[Install]
WantedBy=multi-user.targetKometa (Plex Meta Manager)
Docker Setup
# Add to docker-compose.yml
kometa:
image: kometateam/kometa:latest
container_name: kometa
restart: unless-stopped
environment:
- TZ=America/New_York
- KOMETA_RUN=true
- KOMETA_TIME=05:00
volumes:
- ./kometa/config:/configConfiguration
Create kometa/config/config.yml:
libraries:
Movies:
collection_files:
- pmm: basic
- pmm: imdb
overlay_files:
- pmm: resolution
- pmm: audio_codec
TV Shows:
collection_files:
- pmm: basic
- pmm: imdb
overlay_files:
- pmm: resolution
- pmm: status
plex:
url: http://plex:32400
token: YOUR_PLEX_TOKEN
tmdb:
apikey: YOUR_TMDB_API_KEY
language: enZFS Storage Configuration
Create ZFS Pool
# Create mirrored pool
sudo zpool create plex-data mirror /dev/sda /dev/sdb
# Create datasets
sudo zfs create plex-data/movies
sudo zfs create plex-data/tv
sudo zfs create plex-data/music
# Optimize for media
sudo zfs set recordsize=1M plex-data/movies
sudo zfs set recordsize=1M plex-data/tv
sudo zfs set atime=off plex-dataSnapshots for Backup
# Create snapshot
sudo zfs snapshot plex-data@backup_$(date +%Y%m%d)
# List snapshots
zfs list -t snapshot
# Automatic snapshots with zfs-auto-snapshot
sudo apt install zfs-auto-snapshotHardware Transcoding
Intel Quick Sync
# Check for Intel GPU
ls -la /dev/dri/
# Install drivers
sudo apt install intel-media-va-driver vainfo
# Verify
vainfo
# Add plex user to video group
sudo usermod -aG video plexNVIDIA GPU
# Install NVIDIA drivers
sudo apt install nvidia-driver-535
# Install NVENC
sudo apt install libnvidia-encode-535
# Verify
nvidia-smi
# Docker GPU support
sudo apt install nvidia-docker2
sudo systemctl restart dockerAMD GPU
# Install AMDGPU drivers
sudo apt install mesa-va-drivers vainfo
# Verify
vainfo
# Add user to video group
sudo usermod -aG video plexNetwork File Systems
NFS Mount
# Install NFS client
sudo apt install nfs-common
# Create mount point
sudo mkdir -p /mnt/media
# Mount NFS share
sudo mount -t nfs nas.local:/media /mnt/media
# Add to /etc/fstab
nas.local:/media /mnt/media nfs defaults,_netdev 0 0CIFS/SMB Mount
# Install CIFS utilities
sudo apt install cifs-utils
# Create credentials file
sudo nano /etc/samba/credentialsusername=your_username
password=your_passwordsudo chmod 600 /etc/samba/credentials
# Add to /etc/fstab
//nas.local/media /mnt/media cifs credentials=/etc/samba/credentials,uid=plex,gid=plex,_netdev 0 0API Automation
Python Script
#!/usr/bin/env python3
# plex-manager.py
from plexapi.server import PlexServer
import os
PLEX_URL = os.getenv('PLEX_URL', 'http://localhost:32400')
PLEX_TOKEN = os.getenv('PLEX_TOKEN')
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
def list_libraries():
for section in plex.library.sections():
print(f"{section.key}: {section.title} ({section.type}) - {section.totalSize} items")
def refresh_library(name):
section = plex.library.section(name)
section.refresh()
print(f"Refreshing {name}...")
def search(query):
results = plex.search(query)
for item in results:
print(f"{item.type}: {item.title}")
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
if sys.argv[1] == "list":
list_libraries()
elif sys.argv[1] == "refresh" and len(sys.argv) > 2:
refresh_library(sys.argv[2])
elif sys.argv[1] == "search" and len(sys.argv) > 2:
search(sys.argv[2])
else:
list_libraries()pip3 install plexapi
export PLEX_TOKEN="your-token"
python3 plex-manager.py list
python3 plex-manager.py refresh Movies
python3 plex-manager.py search "inception"Monitoring Stack
Prometheus + Grafana
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
plex-exporter:
image: granra/plex_exporter:latest
container_name: plex-exporter
environment:
- PLEX_SERVER=http://plex:32400
- PLEX_TOKEN=your-token
ports:
- "9594:9594"
volumes:
grafana-data:Security Hardening
Fail2ban Configuration
# Create Plex filter
sudo nano /etc/fail2ban/filter.d/plex.conf[Definition]
failregex = .*\[Auth\].*Failed.*<HOST>.*
ignoreregex =# Add jail
sudo nano /etc/fail2ban/jail.d/plex.conf[plex]
enabled = true
port = 32400
filter = plex
logpath = /var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Logs/Plex Media Server.log
maxretry = 5
bantime = 3600
findtime = 600AppArmor Profile
sudo nano /etc/apparmor.d/usr.lib.plexmediaserver#include <tunables/global>
/usr/lib/plexmediaserver/Plex\ Media\ Server {
#include <abstractions/base>
#include <abstractions/nameservice>
/usr/lib/plexmediaserver/** r,
/var/lib/plexmediaserver/** rw,
/mnt/media/** r,
/dev/dri/** rw,
network inet stream,
network inet dgram,
}Congratulations! 🎉
You’ve mastered advanced Plex configuration on Linux! Your server now features:
- ✅ Docker deployment with hardware acceleration
- ✅ Automated backups and maintenance
- ✅ Monitoring with Tautulli
- ✅ Kometa for metadata management
- ✅ Enterprise security hardening
You’re now a Plex Linux power user!