#!/usr/bin/env bash # ============================================================================= # 50-plex — deploy Plex. HUMAN-IN-THE-LOOP, run by hand, not from bootstrap. # # Usage: # # 1. open https://plex.tv/claim and copy the token # # 2. within four minutes: # sudo PLEX_CLAIM=claim-xxxxxxxxxxxx /srv/mediabox-bootstrap/scripts/50-plex.sh # # A claim token expires four minutes after it is issued. That is the entire # reason this stage is not automated: there is no way to bake one into a USB, # a repo, or a first-boot script and have it still be valid. # # Claiming is only required on the FIRST start. Re-running later without # PLEX_CLAIM is fine and will not re-claim. # ============================================================================= set -uo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DEST="/srv/plex" MASTER="/srv/secrets/stacks.env" # --- gate 1: mounts must be live BEFORE Plex ever scans ---------------------- # If Plex scans a library whose mount is missing, it sees zero files. With a # read-write NAS account, "empty trash after scan" would then delete the # library's records — and Plex has the permission to act on that. Never let # Plex start against absent mounts. echo " checking NAS mounts before starting Plex" missing=0 for mp in /mnt/nas/audiobooks /mnt/nas/education-videos /mnt/nas/health \ /mnt/nas/home-movies /mnt/nas/media /mnt/nas/music-organized \ /mnt/nas/pictures /mnt/nas/radio-shows; do if ls "$mp" >/dev/null 2>&1 && mountpoint -q "$mp"; then printf ' [ok] %s\n' "$mp" else printf ' [FAIL] %s not mounted\n' "$mp" missing=1 fi done if [ "$missing" -ne 0 ]; then echo echo " REFUSING to start Plex with missing mounts." echo " Fix with: sudo /srv/mediabox-bootstrap/scripts/20-cifs.sh --verify" exit 1 fi # --- gate 2: Quick Sync ----------------------------------------------------- if [ ! -e /dev/dri/renderD128 ]; then echo " [WARN] /dev/dri/renderD128 missing — iGPU not enabled in BIOS." echo " Plex will still run, but every transcode will be software." RENDER_GID=993 else RENDER_GID="$(stat -c '%g' /dev/dri/renderD128)" echo " render node gid: $RENDER_GID" fi export RENDER_GID install -d -m 0755 "$DEST" install -d -m 0755 "$DEST/config" chown -R 3000:3000 "$DEST" install -m 0644 "$REPO_DIR/plex/docker-compose.yml" "$DEST/docker-compose.yml" # --- env -------------------------------------------------------------------- set -a TZ="$(grep -E '^TZ=' "$MASTER" 2>/dev/null | head -1 | cut -d= -f2- || echo America/New_York)" PLEX_ADVERTISE_URL="$(grep -E '^PLEX_ADVERTISE_URL=' "$MASTER" 2>/dev/null | head -1 | cut -d= -f2- || echo http://10.0.1.20:32400)" PLEX_CLAIM="${PLEX_CLAIM:-}" set +a if [ -n "$PLEX_CLAIM" ]; then echo " claim token supplied (expires 4 min from issue — moving now)" else echo " no PLEX_CLAIM given; assuming this server is already claimed" fi cd "$DEST" || exit 1 docker compose up -d || { echo " [FAIL] compose up failed"; exit 1; } # The claim token must not linger anywhere on disk. unset PLEX_CLAIM echo " waiting for Plex to answer on 32400" for i in $(seq 1 60); do if curl -fsS -m 3 "http://127.0.0.1:32400/identity" >/dev/null 2>&1; then echo " [ok] Plex is up" break fi sleep 3 done # --- gate 3: disable auto-empty-trash, permanently --------------------------- # This is the single most dangerous default on this box. If a CIFS mount is # missing at scan time Plex sees an empty library; with autoEmptyTrash on it # begins trimming, and the NAS account is read-write. Turn it off in the # config rather than trusting a UI checkbox to stay ticked. PREFS="$DEST/config/Library/Application Support/Plex Media Server/Preferences.xml" if [ -f "$PREFS" ]; then if grep -q 'autoEmptyTrash="0"' "$PREFS"; then echo " [ok] autoEmptyTrash already disabled" else echo " disabling autoEmptyTrash (requires a Plex restart)" docker compose stop plex >/dev/null 2>&1 cp -a "$PREFS" "${PREFS}.bak.$(date +%Y%m%d%H%M%S)" if grep -q 'autoEmptyTrash=' "$PREFS"; then sed -i 's/autoEmptyTrash="[^"]*"/autoEmptyTrash="0"/' "$PREFS" else sed -i 's//dev/null 2>&1 echo " [ok] autoEmptyTrash=0 written" fi else cat <<'MSG' [WARN] Preferences.xml not written yet (first start is still initialising). Re-run this script once Plex has fully started to disable autoEmptyTrash, OR untick it by hand: Settings > Library > "Empty trash automatically after every scan" Do this BEFORE adding any library. With read-write NAS credentials a missing mount plus this setting deletes media records. MSG fi cat <<'NEXT' Next: * Open http://10.0.1.20:32400/web and confirm the server is claimed. * Add libraries pointing at /media/... (the container paths), not /mnt/nas. * Verify a transcode is using Quick Sync: docker exec plex ls -l /dev/dri # start a transcode, then: intel_gpu_top # Video/VideoEnhance rows should be busy NEXT exit 0