Plex¶
Overview¶
Media server with ZFS-backed library.
Data Layout¶
| ZFS Dataset | Container Path | Purpose |
|---|---|---|
| tank/media | /media | Media files (read-only) |
| tank/containers/plex | /config | Plex configuration |
Docker Compose¶
# docker-compose.yml
services:
plex:
image: plexinc/pms-docker:latest
container_name: plex
restart: unless-stopped
environment:
TZ: Europe/Oslo
PLEX_CLAIM: ${PLEX_CLAIM}
PLEX_UID: 1000
PLEX_GID: 1000
volumes:
- /mnt/tank/containers/plex:/config
- /mnt/tank/media:/media:ro
network_mode: host
Environment File¶
Prepare ZFS Datasets¶
# Create config dataset
sudo zfs create tank/containers/plex
# Set permissions
sudo chown -R 1000:1000 /mnt/tank/containers/plex
Media Organization¶
Create nested datasets for separate snapshot policies:
Deploy¶
Access at http://server-ip:32400/web.
Initial Setup¶
- Sign in with Plex account
- Add libraries pointing to
/media/movies,/media/tv, etc. - Configure remote access if needed
Network Mode¶
Using network_mode: host for:
- DLNA discovery
- GDM (Plex discovery)
- Better performance
If you need isolation, use bridge mode with explicit port mappings:
ports:
- "32400:32400"
- "1900:1900/udp"
- "32410:32410/udp"
- "32412:32412/udp"
- "32413:32413/udp"
- "32414:32414/udp"
Hardware Transcoding¶
For hardware transcoding (if not using GPU passthrough):
Note
If GPU is passed through to VM, hardware transcoding won't be available on the host.
Maintenance¶
Update¶
Backup¶
Snapshot the config dataset:
Media doesn't need frequent snapshots (it's write-once, read-many).
Library Optimization¶
Metadata Agents¶
Configure optimal metadata sources in Plex settings:
| Library Type | Recommended Agent |
|---|---|
| Movies | Plex Movie |
| TV Shows | TheTVDB or TMDB |
| Music | Plex Music |
Access via: Settings > Libraries > (Library) > Manage > Edit
Artwork Management¶
Reduce storage and improve performance:
- Limit artwork: Settings > Library > Artwork
- Disable "Include actors' images in local media"
-
Limit poster/backdrop count
-
Optimize existing artwork:
-
Reduce transcoder temp: Add to docker-compose.yml:
Collections¶
Organize content with collections:
- Automatic collections: Enable in library settings
- Based on franchise (MCU, Star Wars, etc.)
-
Genre collections
-
Smart collections: Create via Plex UI
- Filter by year, rating, genre
-
Recently added by type
-
Manual collections: Organize specific items
Troubleshooting¶
Transcoding Issues¶
Transcoder crashes:
# Check logs
docker logs plex 2>&1 | grep -i transcode
# Verify temp directory is writable
docker exec plex ls -la /transcode
# Check available disk space for transcode
df -h /tmp/plex-transcode
Slow transcoding:
- Check hardware transcoding is enabled:
-
Settings > Transcoder > Use hardware acceleration when available
-
Verify GPU access:
-
Monitor transcoding:
Audio transcoding only:
- Usually due to codec mismatch
- Try different audio track
- Consider Plex Pass for hardware audio transcoding
Remote Access Problems¶
Server not accessible remotely:
-
Check port forwarding:
-
Verify firewall:
-
Test manual port:
- Settings > Remote Access > Manually specify public port
- Try 32400
Relay mode (slow):
- Port forwarding not working
- Check router UPnP or manual forwarding
- Verify ISP doesn't block port
Database Corruption¶
Symptoms: Missing items, slow library, crashes
Repair:
# Stop Plex
docker compose stop plex
# Backup database
cp /mnt/tank/containers/plex/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db \
/mnt/tank/backups/plex-db-$(date +%Y%m%d).db
# Start Plex (it will repair on startup)
docker compose start plex
# Check logs for repair status
docker logs plex 2>&1 | grep -i database
Full database rebuild (last resort):
# Stop Plex
docker compose stop plex
# Remove database (metadata will be re-downloaded)
rm /mnt/tank/containers/plex/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db*
# Start Plex
docker compose start plex
# Re-scan all libraries via UI
Playback Issues¶
Buffering:
- Check network bandwidth
- Reduce streaming quality in client
- Enable Direct Play/Direct Stream where possible
"Server not powerful enough":
- Lower transcoding quality
- Enable hardware transcoding
- Pre-transcode using optimized versions
Subtitles causing transcode:
- Use SRT subtitles instead of image-based
- Enable "Burn subtitles" = "Automatic"
Restore Procedure¶
Config Restoration from Snapshot¶
-
Stop Plex:
-
Identify snapshot:
-
Rollback:
-
Restart:
-
Verify:
- Access web UI
- Check libraries are present
- Verify watched status
Metadata Recovery¶
If config is lost but media files exist:
-
Start fresh Plex container
-
Re-add libraries pointing to same media paths
-
Use Plex's "Scan Library Files" for each library
-
Watched status recovery:
- Trakt plugin can restore watched status
- Or restore from database backup
Database Backup and Restore¶
Create regular database backups:
#!/bin/bash
# /usr/local/bin/backup-plex-db.sh
PLEX_DB="/mnt/tank/containers/plex/Library/Application Support/Plex Media Server/Plug-in Support/Databases"
BACKUP_DIR="/mnt/tank/backups/plex"
mkdir -p "$BACKUP_DIR"
# Stop Plex briefly for consistent backup
docker compose -f ~/docker/plex/docker-compose.yml stop plex
# Copy database files
cp "$PLEX_DB/com.plexapp.plugins.library.db" \
"$BACKUP_DIR/library-$(date +%Y%m%d).db"
# Restart Plex
docker compose -f ~/docker/plex/docker-compose.yml start plex
# Keep last 7 backups
find "$BACKUP_DIR" -name "library-*.db" -mtime +7 -delete
Restore from database backup: