Skip to content

itsFelixH/media-server-scripts

Repository files navigation

Media Server Scripts

Maintenance and monitoring scripts for a Plex media server stack running on a Raspberry Pi (or any Linux box). Handles health checks, backups, library reporting, media analysis, and scheduled maintenance.

The Stack

Service What it does Schedule Links
Plex Media streaming server Always running Support
Kometa Metadata, collections, and overlay management for Plex Daily at 05:00 (internal scheduler) Wiki
UMTK Upcoming movies/TV shows + TV show status overlays for Kometa Daily at 02:00 (Docker internal cron) Docs
PlexTraktSync Syncs Plex watch history and ratings with Trakt Always running (systemd) Docs
ImageMaid Plex metadata image cleanup and DB optimization Weekly Sundays at 07:00 (Docker internal) GitHub
Radarr Movie management and downloads Always running (systemd)
Sonarr TV show management and downloads Always running (systemd)

The scripts monitor, maintain, and report on this stack. They don't replace any of these tools — they wrap around them to keep everything healthy and give you visibility into your library.

Quick Start

# 1. Clone the repo
git clone git@github.com:itsFelixH/media-server-scripts.git ~/kometa/scripts
cd ~/kometa/scripts

# 2. Create your config from the template
cp config.yml.template config.yml

# 3. Fill in your values (see Configuration section below)
nano config.yml

# 4. Test a script
bash healthcheck.sh

Requirements

  • OS: Linux (tested on Raspberry Pi OS / Debian)
  • Shell: Bash
  • Core tools: jq, curl
  • Media analysis: ffprobe (from ffmpeg)
  • Metadata audit: python3, python3-yaml
  • Docker: For container management (Kometa, UMTK, ImageMaid, etc.)
  • systemd: For service monitoring (Plex, Radarr, Sonarr)

Scripts Overview

Script Purpose Schedule
healthcheck.sh Monitor services, disk, memory, temperature, APIs Every 30 min
maintenance.sh System updates, Docker updates, log rotation, diagnostics Mondays 03:00
backup.sh Archive all configs to media drive Sundays 01:00
archive-reports.sh Copy changed reports to archive with date stamps Daily 05:30
library-catalog.sh Snapshot library contents with diff tracking Sundays 01:30
metadata-audit.sh Validate metadata files against library Sundays 02:00
encode-queue.sh Find re-encoding candidates 1st of month
storage-report.sh Disk usage breakdown by folder/codec/resolution 28th of month
media-analyzer.sh Filter/analyze video files by codec, resolution, size Manual
runkometa.sh Interactive Kometa runner with library/mode selection Manual

All scripts support -h/--help and --no-discord. Scripts with terminal output support -q/--quiet for cron use.


Configuration

All scripts load settings from config.yml via the shared config.sh loader. The config file is gitignored (contains secrets).

Copy config.yml.template to config.yml and fill in your values. The template is fully commented with what each key does.

Config structure

The config is organized into four sections:

  1. Credentialsplex (url, token), discord (alerts, notifications webhooks), api_keys (radarr, sonarr)
  2. Pathsmedia (movies, tv), tools (kometa, umtk, imagemaid, compose_files list), output (logs, reports), backup (configs, reports)
  3. Servicesserver (hostname), services (plex service name, arr list, docker_containers list)
  4. Tuningretention_days (single value applied to all logs/backups), notifications (on_success, on_failure)

Thresholds (disk %, memory %, temperature, stale task minutes) are hardcoded in config.sh with sensible defaults — no config needed.

Using a single script? You only need to fill in the keys that script uses (plus server.hostname). Leave everything else empty or remove it — config.sh won't fail on missing optional keys, it just skips those checks.


healthcheck.sh — services, containers, disk, memory, Plex API

Runs silently. Only alerts Discord when something is wrong. Auto-restarts failed Docker containers.

Config keys used

plex.*, api_keys.*, services.*, tools.kometa, tools.umtk

What it checks

  • systemd services (Plex, Radarr, Sonarr, Bazarr)
  • Docker containers running + healthy (Kometa, UMTK, ImageMaid)
  • Root disk and media drive usage
  • RAM and swap usage
  • CPU temperature
  • Plex API responding + token valid
  • Radarr/Sonarr API responding (skipped if keys empty)
  • Internet + TMDb reachability
  • UMTK, Kometa, PlexTraktSync last run times

Behavior

  • All healthy → silent exit, one-line heartbeat in log
  • Issues found → consolidated Discord alert to #server-alerts
  • Same issues as last run → no repeat alert (deduplication)
  • Issues resolved → recovery notification with strikethrough list
maintenance.sh — system updates, Docker, log rotation, diagnostics

Interactive menu with 11 maintenance tasks. Also runs unattended via --scheduled.

Config keys used

services.*, tools.*, retention_days

Menu options

 1: System Maintenance       (apt update/upgrade/autoremove)
 2: Update Media Tools       (PlexTraktSync self-update)
 3: Update Docker Containers (pull latest images, restart)
 4: Restart Services         (Plex, arr services, Docker containers)
 5: Disk Maintenance         (clean old logs, show usage)
 6: Health Check             (services, disk, memory, load, connectivity)
 7: Temperature Check        (thermal zones)
 8: Network Check            (TMDb, Trakt, DNS)
 9: Process Monitor          (zombies, top CPU)
10: Config Validation        (YAML syntax for all configs)
11: Token Consistency Check  (compare Plex token across configs)

Scheduled mode

bash maintenance.sh --scheduled

Runs tasks 1, 2, 3, 5, 10, 11 unattended. Sends summary to Discord.

backup.sh — config archival with retention

Creates a zip archive of all critical configs and scripts. Output filename: <hostname>-backup-YYYYMMDD.zip. Manages retention automatically.

Config keys used

backup.configs, tools.*, retention_days, server.hostname

What gets backed up

  • All *.yml from the Kometa config directory
  • Kometa metadata directory (if it contains yml files)
  • All *.yml from the UMTK config directory
  • ImageMaid config (.env)
  • Docker compose files (from tools.compose_files list)
  • Scripts config (config.yml)
  • Crontab
archive-reports.sh — daily report archiver

Copies new or changed markdown reports to the archive location with date-stamped filenames. Only archives when content has actually changed.

Config keys used

output.reports, backup.reports

Behavior

  • Reads reports from output.reports directory
  • Archives to backup.reports in per-report subdirectories
  • Filenames: <report-name>-YYYY-MM-DD.md
  • Skips unchanged reports (diff comparison against latest archived copy)
  • Checks that the archive mount is available before writing
library-catalog.sh — library snapshot with diff tracking

Generates a full markdown listing of all movies and TV shows. Compares against the previous run to highlight additions and removals.

Config keys used

media.*, plex.*

Output

  • Report: reports/library-catalog.md (overwritten each run)
  • Previous: reports/library-catalog.prev.md (for diffing)
  • Discord: library totals + changes since last run
metadata-audit.sh — validate metadata against library

Checks Kometa metadata YAML files against actual library content. Finds orphaned entries, missing metadata, duplicates, and season/episode gaps.

Config keys used

tools.kometa (metadata dir derived), media.*

What it checks

  • Orphaned metadata (entries for content not in library)
  • Missing metadata (library items without custom entries)
  • Duplicate entries across files
  • Season/episode coverage gaps

Dependencies

python3, python3-yaml, jq, curl

encode-queue.sh — find re-encoding candidates

Scans for non-HEVC/non-AV1 files and generates a prioritized re-encode list sorted by size. Estimates space savings. Does NOT perform any encoding.

Config keys used

media.*

Usage

./encode-queue.sh                              # Both libraries, files >1GB
./encode-queue.sh "/mnt/Media/Movies"          # Movies only
./encode-queue.sh --min-size=2 --limit=20      # Only >2GB, top 20

Dependencies

ffprobe (ffmpeg), jq, curl

storage-report.sh — disk usage by folder, codec, resolution

Scans a media directory and generates a detailed storage report. Auto-detects TV (show/season) vs Movies (flat) structure. Compares against previous run.

Config keys used

media.tv (default scan directory)

Usage

./storage-report.sh                            # TV Shows (default)
./storage-report.sh "/mnt/Media/Movies"        # Movies

Dependencies

ffprobe (ffmpeg), jq, curl

media-analyzer.sh — filter/analyze video files

Scans video files, probes each for codec and resolution, filters by mode. Supports scanning multiple directories.

Config keys used

media.*

Modes

Mode Description
all Full analysis (default)
non-hevc Files NOT encoded in HEVC/x265
hevc HEVC/x265 files only
av1 AV1 files only
h264 H.264/x264 files only
non-hd Below 720p
4k 2160p+ files
large Files exceeding size threshold

Usage

./media-analyzer.sh non-hevc "/mnt/Media/Movies"
./media-analyzer.sh av1
./media-analyzer.sh all "/mnt/Media/TV Shows" "/mnt/Media/Movies"
./media-analyzer.sh --quiet large "/mnt/Media/TV Shows"

Dependencies

ffprobe (ffmpeg), jq, curl

runkometa.sh — interactive Kometa runner

Menu-driven interface for running Kometa inside its Docker container with different options.

Options

  • Full run (all libraries)
  • Ignore schedules
  • Per-library (Movies / TV Shows)
  • Per-mode (metadata, collections, overlays)
  • Delete all collections

Crontab Setup

# Health check (every 30 minutes)
*/30 * * * * bash ~/kometa/scripts/healthcheck.sh

# Weekly config backup (Sundays 01:00)
0 1 * * 0 bash ~/kometa/scripts/backup.sh

# Library catalog (Sundays 01:30)
30 1 * * 0 bash ~/kometa/scripts/library-catalog.sh --quiet

# Metadata audit (Sundays 02:00)
0 2 * * 0 bash ~/kometa/scripts/metadata-audit.sh --quiet

# Scheduled maintenance (Mondays 03:00)
0 3 * * 1 bash ~/kometa/scripts/maintenance.sh --scheduled

# Encode queue (1st of month 04:00)
0 4 1 * * bash ~/kometa/scripts/encode-queue.sh --quiet

# Storage report (28th of month 04:30)
30 4 28 * * bash ~/kometa/scripts/storage-report.sh --quiet

# Archive reports (daily 05:30)
30 5 * * * bash ~/kometa/scripts/archive-reports.sh --quiet

The Docker-based services have their own internal schedules:

Service Schedule Managed by
Kometa Daily at 05:00 KOMETA_TIMES env var in compose
UMTK Daily at 02:00 Internal cron in container
ImageMaid Weekly Sundays at 07:00 SCHEDULE in .env

Discord Notifications

All scripts share a single discord_notify function defined in config.sh. No per-script notification code needed.

Levels

Level Webhook Use case
success discord.notifications Successful runs, completions
warning discord.alerts Non-critical issues
error discord.alerts Failures, things that need attention

The footer on every notification automatically includes the hostname, script name, and run duration.

Control which messages are sent via notifications.on_success and notifications.on_failure in config. Use --no-discord per-run to suppress entirely.


File Structure

~/kometa/scripts/
├── config.yml              # Your config (gitignored, contains secrets)
├── config.yml.template     # Template with full documentation
├── config.sh               # Config loader + discord_notify function
├── healthcheck.sh
├── maintenance.sh
├── backup.sh
├── archive-reports.sh
├── runkometa.sh
├── library-catalog.sh
├── metadata-audit.sh
├── media-analyzer.sh
├── storage-report.sh
├── encode-queue.sh
├── logs/                   # Per-script log subdirectories (gitignored)
│   ├── archive-reports/
│   ├── backup/
│   ├── healthcheck/
│   ├── maintenance/
│   └── ...
└── reports/                # Generated markdown reports (gitignored)

Related Projects

  • Kometa — Metadata, collections, and overlays for Plex
  • UMTK — Upcoming movies/TV shows + status overlays
  • PlexTraktSync — Syncs Plex watch history and ratings with Trakt
  • ImageMaid — Plex image cleanup and DB optimization
  • WTWP — Group swiping app to decide what to watch

About

Maintenance and monitoring scripts for a Plex media server stack — health checks, backups, library reporting, and scheduled maintenance.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages