Mike 2026-08-20, revising the 2026-07-31 iGPU-only call with the 2026-08-04 finding that this UHD 630 has no HEVC encode entrypoint. runtime: nvidia + NVIDIA_VISIBLE_DEVICES/CAPABILITIES on the plex service; /dev/dri stays. Also brings the compose current with the live opt-in watchtower config, and 50-plex.sh now sources WATCHTOWER_NOTIFICATION_URL (carries the publish token) from stacks.env, soft-gates on nvidia-smi, and adds the NVENC line to the walk-away checks.
175 lines
6.9 KiB
Bash
Executable File
175 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# 50-plex — start Plex against the MIGRATED data directory.
|
|
#
|
|
# Usage: sudo /srv/mediabox-bootstrap/scripts/50-plex.sh
|
|
#
|
|
# NO CLAIM TOKEN. This is deliberate and important.
|
|
#
|
|
# The migration carries MachineIdentifier, ProcessedMachineIdentifier and the
|
|
# online token across in Preferences.xml, so this server IS the existing
|
|
# server: already claimed, shared users still invited, clients still pointed
|
|
# at it. Claiming would mint a NEW identity and throw all of that away — the
|
|
# exact thing the migration exists to preserve.
|
|
#
|
|
# If you find yourself reaching for https://plex.tv/claim, stop. Something has
|
|
# gone wrong with the Preferences.xml step in migration/README.md § M3.
|
|
# =============================================================================
|
|
set -uo pipefail
|
|
|
|
PLEXDIR="/srv/plex"
|
|
CFG="$PLEXDIR/config/Library/Application Support/Plex Media Server"
|
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
MASTER="/srv/secrets/stacks.env"
|
|
|
|
# The six shares, named exactly as the database stores them.
|
|
MOUNTS=(
|
|
"/mnt/nas/media"
|
|
"/mnt/nas/Radio Shows"
|
|
"/mnt/nas/Education Videos"
|
|
"/mnt/nas/Health"
|
|
"/mnt/nas/Home Movies"
|
|
"/mnt/nas/Pictures"
|
|
)
|
|
|
|
ok(){ printf ' \033[1;32m[ok]\033[0m %s\n' "$*"; }
|
|
bad(){ printf ' \033[1;31m[FAIL]\033[0m %s\n' "$*"; }
|
|
note(){ printf ' %s\n' "$*"; }
|
|
|
|
[ "$(id -u)" -eq 0 ] || { bad "must run as root"; exit 1; }
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Gate 1 — every mount live BEFORE Plex ever opens the database.
|
|
#
|
|
# If Plex scans a library whose mount is absent it sees zero files. The NAS
|
|
# account is read-write, so with autoEmptyTrash on that becomes deletion it
|
|
# has permission to perform. gen-preferences.ps1 forces autoEmptyTrash=0, but
|
|
# this gate is the belt to that braces.
|
|
# ---------------------------------------------------------------------------
|
|
echo " checking the six NAS mounts"
|
|
missing=0
|
|
for mp in "${MOUNTS[@]}"; do
|
|
if mountpoint -q "$mp" && ls "$mp" >/dev/null 2>&1; then
|
|
ok "$mp"
|
|
else
|
|
bad "$mp not mounted"
|
|
missing=1
|
|
fi
|
|
done
|
|
if [ "$missing" -ne 0 ]; then
|
|
echo
|
|
bad "REFUSING to start Plex with missing mounts."
|
|
note "fix: sudo /srv/mediabox-bootstrap/scripts/20-cifs.sh --verify"
|
|
exit 1
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Gate 2 — the database must actually be migrated.
|
|
#
|
|
# Starting Plex against an un-remapped database means every item shows as
|
|
# unavailable, and the recovery is messier than simply not starting.
|
|
# ---------------------------------------------------------------------------
|
|
DB="$CFG/Plug-in Support/Databases/com.plexapp.plugins.library.db"
|
|
if [ ! -f "$DB" ]; then
|
|
bad "no database at $DB"
|
|
note "restore the data directory first — migration/README.md § M3"
|
|
exit 1
|
|
fi
|
|
if grep -qac 'korval' "$DB" 2>/dev/null && grep -qac '\\\\korval\\' "$DB" 2>/dev/null; then
|
|
bad "database still contains Windows UNC paths — remap has not been run"
|
|
note "run: sudo /srv/mediabox-bootstrap/migration/migrate-db.sh \"$DB\""
|
|
exit 1
|
|
fi
|
|
ok "database present and remapped"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Gate 3 — identity preserved?
|
|
# ---------------------------------------------------------------------------
|
|
PREFS="$CFG/Preferences.xml"
|
|
if [ -f "$PREFS" ] && grep -q 'ProcessedMachineIdentifier=' "$PREFS"; then
|
|
ok "server identity present in Preferences.xml (no claim needed)"
|
|
else
|
|
bad "Preferences.xml missing or has no ProcessedMachineIdentifier"
|
|
note "generate it on the Windows box: migration/gen-preferences.ps1"
|
|
note "without it this becomes a NEW server and shared users are lost"
|
|
exit 1
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Quick Sync
|
|
# ---------------------------------------------------------------------------
|
|
if [ -e /dev/dri/renderD128 ]; then
|
|
RENDER_GID="$(stat -c '%g' /dev/dri/renderD128)"
|
|
ok "render node gid $RENDER_GID"
|
|
else
|
|
RENDER_GID=993
|
|
note "[warn] /dev/dri/renderD128 missing — iGPU not enabled in BIOS."
|
|
note " Plex will run, but every transcode will be software."
|
|
fi
|
|
export RENDER_GID
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# NVIDIA — wired in beside Quick Sync 2026-08-20. NVENC is the only hardware
|
|
# HEVC encode on this box. Soft gate: Plex still starts without it, loudly.
|
|
# ---------------------------------------------------------------------------
|
|
if nvidia-smi -L >/dev/null 2>&1; then
|
|
ok "NVIDIA answers: $(nvidia-smi -L | head -1)"
|
|
else
|
|
note "[warn] nvidia-smi not answering — Plex will start, but HEVC-out"
|
|
note " transcodes fall back to software until driver/toolkit is fixed."
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Deploy
|
|
# ---------------------------------------------------------------------------
|
|
install -d -m 0755 "$PLEXDIR"
|
|
install -m 0644 "$REPO_DIR/plex/docker-compose.yml" "$PLEXDIR/docker-compose.yml"
|
|
chown -R 3000:3000 "$PLEXDIR/config"
|
|
|
|
set -a
|
|
TZ="$(grep -E '^TZ=' "$MASTER" 2>/dev/null | head -1 | cut -d= -f2- || echo America/New_York)"
|
|
# Watchtower's ntfy URL carries the publish token, so it lives in stacks.env on
|
|
# the host and is sourced here — never hardcoded in the compose file.
|
|
WATCHTOWER_NOTIFICATION_URL="$(grep -E '^WATCHTOWER_NOTIFICATION_URL=' "$MASTER" 2>/dev/null | head -1 | cut -d= -f2-)"
|
|
set +a
|
|
|
|
cd "$PLEXDIR" || exit 1
|
|
docker compose up -d || { bad "compose up failed"; exit 1; }
|
|
|
|
echo " waiting for Plex"
|
|
for i in $(seq 1 60); do
|
|
if curl -fsS -m 3 "http://127.0.0.1:32400/identity" >/dev/null 2>&1; then
|
|
ok "Plex is up"
|
|
break
|
|
fi
|
|
sleep 3
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Verify the migration actually landed
|
|
# ---------------------------------------------------------------------------
|
|
ID="$(curl -fsS -m 5 http://127.0.0.1:32400/identity 2>/dev/null | grep -o 'machineIdentifier="[^"]*"' | cut -d'"' -f2)"
|
|
if [ "$ID" = "eb69ec8a9f38b64eeafe911e26d89baeaa78f0e3" ]; then
|
|
ok "machineIdentifier matches the original server — identity preserved"
|
|
else
|
|
bad "machineIdentifier is $ID, expected eb69ec8a9f38b64eeafe911e26d89baeaa78f0e3"
|
|
note "this is a DIFFERENT server. Shared users and client registrations are lost."
|
|
note "stop, and check the Preferences.xml step before adding anything."
|
|
fi
|
|
|
|
cat <<'NEXT'
|
|
|
|
Verify before you walk away:
|
|
* https://plex.tv/claim was NOT used and must not be.
|
|
* Movies should show 1,360 titles; TV Shows 23,493 episodes.
|
|
* Continue Watching should be populated — that is the whole point.
|
|
* A remote client that already had this server should still see it
|
|
without re-adding.
|
|
* Force a transcode, then: sudo intel_gpu_top
|
|
Video / VideoEnhance rows should be busy.
|
|
* Force an HEVC-out transcode, then: nvidia-smi
|
|
Plex Transcoder should hold an ENC session on the 1070.
|
|
NEXT
|
|
|
|
exit 0
|