diff --git a/plex32_update_check.sh b/plex32_update_check.sh
index 02ecee2..7f11275 100644
--- a/plex32_update_check.sh
+++ b/plex32_update_check.sh
@@ -47,61 +47,38 @@ fi
echo "[INFO] APT updates available: $APT_UPDATES"
# =============================================================
-# STEP 2 — CHECK PLEX DOCKER IMAGE UPDATE
+# STEP 2 — CHECK PLEX DOCKER IMAGE UPDATE (SKOPEO MANIFEST CHECK)
# =============================================================
-echo "[INFO] Checking Plex Docker image..."
+echo "[INFO] Checking Plex Docker image via Skopeo..."
PLEX_FAILED=false
PLEX_UPDATE_AVAILABLE=false
PLEX_ERROR_HTML=""
-# lscr.io occasionally returns "error from registry: unauthorized" on the
-# final manifest step of a large multi-layer pull, even after every layer
-# downloaded successfully — a transient token/rate-limit issue on their end,
-# not a credentials problem. Retry a few times before treating it as a real
-# failure, since it usually resolves within one or two attempts.
-PLEX_PULL_MAX_RETRIES=3
-PLEX_PULL_RETRY_DELAY=30
-plex_pull_attempt=1
-PLEX_PULL_STATUS=1
-PLEX_PULL_OUTPUT=""
+# Fetch digest of remote latest image from lscr.io
+REMOTE_DIGEST=$(skopeo inspect docker://lscr.io/linuxserver/plex:latest --format '{{.Digest}}' 2>/dev/null)
-while [ $plex_pull_attempt -le $PLEX_PULL_MAX_RETRIES ]; do
- PLEX_PULL_OUTPUT=$(docker pull lscr.io/linuxserver/plex:latest 2>&1)
- PLEX_PULL_STATUS=$?
- if [ $PLEX_PULL_STATUS -eq 0 ]; then
- break
- fi
- echo "[WARN] docker pull attempt $plex_pull_attempt/$PLEX_PULL_MAX_RETRIES failed (exit $PLEX_PULL_STATUS)."
- if [ $plex_pull_attempt -lt $PLEX_PULL_MAX_RETRIES ]; then
- echo "[WARN] Retrying in ${PLEX_PULL_RETRY_DELAY}s..."
- sleep $PLEX_PULL_RETRY_DELAY
- fi
- plex_pull_attempt=$((plex_pull_attempt + 1))
-done
+# Fetch digest of currently running/local image
+LOCAL_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'@' -f2)
-PLEX_IMAGE_VERSION=$(docker inspect lscr.io/linuxserver/plex:latest --format '{{index .Config.Labels "build_version"}}' 2>/dev/null || echo "unknown")
-CURRENT_IMAGE_DATE=$(docker inspect --format='{{.Created}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'T' -f1)
-
-if [ $PLEX_PULL_STATUS -ne 0 ]; then
+if [ -z "$REMOTE_DIGEST" ]; then
PLEX_FAILED=true
- PLEX_STATUS_TEXT="Check failed after $PLEX_PULL_MAX_RETRIES attempts — see error detail below"
- echo "[ERROR] docker pull failed after $PLEX_PULL_MAX_RETRIES attempts. Final output:"
- echo "$PLEX_PULL_OUTPUT"
- PLEX_ERROR_HTML="
⚠ Docker Pull Error (exit $PLEX_PULL_STATUS, after $PLEX_PULL_MAX_RETRIES attempts)
$(echo "$PLEX_PULL_OUTPUT" | sed 's/&/\&/g; s/\</g; s/>/\>/g')
"
-elif echo "$PLEX_PULL_OUTPUT" | grep -q "Pull complete"; then
+ PLEX_STATUS_TEXT="Check failed — unable to reach registry manifest"
+ echo "[ERROR] skopeo inspect failed to fetch digest for lscr.io/linuxserver/plex:latest"
+ PLEX_ERROR_HTML="⚠ Registry Query Error
Failed to inspect remote image digest from lscr.io via skopeo.
"
+elif [ "$REMOTE_DIGEST" != "$LOCAL_DIGEST" ]; then
PLEX_UPDATE_AVAILABLE=true
- PLEX_STATUS_TEXT="Update available — new image pulled"
- if [ $plex_pull_attempt -gt 1 ]; then
- PLEX_STATUS_TEXT="$PLEX_STATUS_TEXT (succeeded on retry, attempt $plex_pull_attempt)"
- fi
+ PLEX_STATUS_TEXT="Update available — new digest found on registry"
else
PLEX_STATUS_TEXT="Up to date"
fi
+PLEX_IMAGE_VERSION=$(docker inspect lscr.io/linuxserver/plex:latest --format '{{index .Config.Labels "build_version"}}' 2>/dev/null || echo "unknown")
+CURRENT_IMAGE_DATE=$(docker inspect --format='{{.Created}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'T' -f1)
+
echo "[INFO] Plex status: $PLEX_STATUS_TEXT"
# =============================================================
-# STEP 2B — VERIFY RUNNING CONTAINER (independent of pull result)
+# STEP 2B — VERIFY RUNNING CONTAINER
# =============================================================
echo "[INFO] Checking actual running Plex container..."
@@ -169,25 +146,27 @@ ANY_UPDATES=false
[ "$F2B_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true
[ "$DOCKER_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true
-# A failed registry pull (rate-limit, transient network blip, etc.) is not the
-# same severity as the actual Plex container being down. If the pull check
-# failed but the running container is confirmed healthy, badge it as a lower
-# severity "registry check failed" rather than a full CHECK FAILED/critical state.
+# Prioritize status:
+# 1. Container Down (Red)
+# 2. Updates Available (Blue) - Shows update banner even if a non-critical check warning occurred
+# 3. Check Failed (Amber) - Only if checks failed AND no updates were found
+# 4. All Current (Green)
+
if [ "$CONTAINER_OK" = false ]; then
STATUS_COLOR="#b91c1c"
STATUS_BADGE="🔴 CONTAINER DOWN"
STATUS_BANNER_MSG="🔴 Plex container is NOT running — investigate immediately"
SUBJECT="🔴 PLEX32 — Plex Container Down — $DATE_SHORT"
-elif [ "$ANY_FAILED" = true ]; then
- STATUS_COLOR="#b45309"
- STATUS_BADGE="⚠ CHECK FAILED"
- STATUS_BANNER_MSG="⚠ Registry/update check failed, but Plex container itself is confirmed running — no action required unless this repeats daily"
- SUBJECT="⚠ PLEX32 — Update Check Failed — $DATE_SHORT"
elif [ "$ANY_UPDATES" = true ]; then
STATUS_COLOR="#1d6fa8"
STATUS_BADGE="🔄 UPDATES AVAILABLE"
- STATUS_BANNER_MSG="🔄 Updates are available for one or more components"
+ STATUS_BANNER_MSG="🔄 Updates are available for one or more components — run commands below to apply"
SUBJECT="🔄 PLEX32 — Updates Available — $DATE_SHORT"
+elif [ "$ANY_FAILED" = true ]; then
+ STATUS_COLOR="#b45309"
+ STATUS_BADGE="⚠ CHECK FAILED"
+ STATUS_BANNER_MSG="⚠ Update check experienced a registry/network error — Plex container itself is running normally"
+ SUBJECT="⚠ PLEX32 — Update Check Failed — $DATE_SHORT"
else
STATUS_COLOR="#1a7f4b"
STATUS_BADGE="✅ ALL CURRENT"
@@ -196,7 +175,7 @@ else
fi
# =============================================================
-# STEP 6 — BUILD COMMAND BLOCKS (click to select)
+# STEP 6 — BUILD COMMAND BLOCKS
# =============================================================
make_cmd_block() {
local step_num="$1"
@@ -223,6 +202,7 @@ if [ "$ANY_UPDATES" = true ]; then
if [ "$PLEX_UPDATE_AVAILABLE" = true ]; then
CMD="cd ~/docker/plex
+docker compose pull
docker compose up -d"
UPDATE_COMMANDS_HTML+=$(make_cmd_block "$STEP" "Plex Media Server (Docker)" "$CMD")
STEP=$((STEP+1))