diff --git a/plex32_backup2.sh b/plex32_backup2.sh
deleted file mode 100644
index af06a64..0000000
--- a/plex32_backup2.sh
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/bin/bash
-# =============================================================
-# PLEX32 — Config Backup Script
-# Creates tar archives of Plex and Tautulli configs
-# Copies to NAS08 via NFS as single files
-# Keeps last 3 backups, deletes older ones
-# Sends HTML email report in KingDezigns style
-# Location: /usr/scripts/plex32/plex32_backup.sh
-# Schedule: Every 3 days at 2:00 AM (cron)
-# =============================================================
-
-# --- Config ---
-HOSTNAME="plex32"
-PLEX_SRC="/opt/plex/config"
-TAUTULLI_SRC="/opt/tautulli/config"
-NFS_DEST="/mnt/plex/config"
-TAUTULLI_LOC="backups/tautulli"
-PLEX_LOC="backups/plex"
-
-TMP_DIR="/tmp/plex32-backup"
-LOG_DIR="/var/log/plex32-backup"
-LOG_FILE="$LOG_DIR/backup-$(date +%Y%m%d).log"
-RETENTION_COUNT=3
-COMPOSE_DIR="/home/rufusking/docker/plex"
-
-DATESTAMP=$(date '+%Y-%m-%d')
-TIMESTAMP=$(date '+%B %d, %Y at %I:%M %p')
-
-PLEX_ARCHIVE="plex-config-${DATESTAMP}.tar.gz"
-TAUTULLI_ARCHIVE="tautulli-config-${DATESTAMP}.tar.gz"
-
-SMTP_SERVER="smtppro.zoho.com"
-SMTP_PORT=465
-SMTP_USER="rufus.king@kingdezigns.com"
-SMTP_PASS="$(cat /etc/plex32-smtp-pass 2>/dev/null)"
-EMAIL_TO="rufus.king@kingdezigns.com"
-EMAIL_FROM="rufus.king@kingdezigns.com"
-
-# --- Setup ---
-mkdir -p "$LOG_DIR" "$TMP_DIR"
-START_TIME=$(date +%s)
-
-exec > >(tee -a "$LOG_FILE") 2>&1
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] PLEX32 backup started"
-
-# --- Check NFS mount ---
-if ! mountpoint -q "$NFS_DEST"; then
- echo "[ERROR] NFS mount not available: $NFS_DEST"
- exit 1
-fi
-
-# --- Stop containers ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Stopping Plex and Tautulli containers..."
-cd "$COMPOSE_DIR" && docker compose down
-STOP_STATUS=$?
-if [ $STOP_STATUS -ne 0 ]; then
- echo "[ERROR] Failed to stop containers cleanly"
-fi
-
-# --- Tar Plex config ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Creating Plex config archive..."
-PLEX_START=$(date +%s)
-tar -czf "$TMP_DIR/$PLEX_ARCHIVE" \
- --exclude="config/Library/Application Support/Plex Media Server/Cache" \
- --exclude="config/Library/Application Support/Plex Media Server/Logs" \
- --exclude="config/Library/Application Support/Plex Media Server/Crash Reports" \
- -C /opt/plex config 2>&1
-PLEX_TAR_STATUS=$?
-PLEX_END=$(date +%s)
-PLEX_DURATION=$((PLEX_END - PLEX_START))
-
-if [ $PLEX_TAR_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Plex archive created in ${PLEX_DURATION}s"
-else
- echo "[ERROR] Plex tar failed with status $PLEX_TAR_STATUS"
-fi
-
-# --- Tar Tautulli config ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Creating Tautulli config archive..."
-TAUTULLI_START=$(date +%s)
-tar -czf "$TMP_DIR/$TAUTULLI_ARCHIVE" \
- -C /opt/tautulli config 2>&1
-TAUTULLI_TAR_STATUS=$?
-TAUTULLI_END=$(date +%s)
-TAUTULLI_DURATION=$((TAUTULLI_END - TAUTULLI_START))
-
-if [ $TAUTULLI_TAR_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Tautulli archive created in ${TAUTULLI_DURATION}s"
-else
- echo "[ERROR] Tautulli tar failed with status $TAUTULLI_TAR_STATUS"
-fi
-
-# --- Restart containers ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restarting containers..."
-cd "$COMPOSE_DIR" && docker compose up -d
-START_STATUS=$?
-if [ $START_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Containers restarted successfully"
-else
- echo "[ERROR] Failed to restart containers — manual intervention required"
-fi
-
-# --- Copy Plex archive to NAS08 ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Copying Plex archive to NAS08..."
-COPY_PLEX_START=$(date +%s)
-cp "$TMP_DIR/$PLEX_ARCHIVE" "$NFS_DEST/$PLEX_LOC/"
-PLEX_COPY_STATUS=$?
-COPY_PLEX_END=$(date +%s)
-PLEX_COPY_DURATION=$((COPY_PLEX_END - COPY_PLEX_START))
-
-if [ $PLEX_COPY_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Plex archive copied in ${PLEX_COPY_DURATION}s"
-else
- echo "[ERROR] Plex archive copy failed"
-fi
-
-# --- Copy Tautulli archive to NAS08 ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Copying Tautulli archive to NAS08..."
-COPY_TAUTULLI_START=$(date +%s)
-cp "$TMP_DIR/$TAUTULLI_ARCHIVE" "$NFS_DEST/$TAUTULLI_LOC/"
-TAUTULLI_COPY_STATUS=$?
-COPY_TAUTULLI_END=$(date +%s)
-TAUTULLI_COPY_DURATION=$((COPY_TAUTULLI_END - COPY_TAUTULLI_START))
-
-if [ $TAUTULLI_COPY_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Tautulli archive copied in ${TAUTULLI_COPY_DURATION}s"
-else
- echo "[ERROR] Tautulli archive copy failed"
-fi
-
-# --- Rotate old backups — keep last 3 ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Rotating old backups..."
-ls -t "$NFS_DEST/$PLEX_LOC"/plex-config-*.tar.gz 2>/dev/null | tail -n +$((RETENTION_COUNT + 1)) | xargs rm -f
-ls -t "$NFS_DEST/$TAUTULLI_LOC"/tautulli-config-*.tar.gz 2>/dev/null | tail -n +$((RETENTION_COUNT + 1)) | xargs rm -f
-
-# --- Cleanup temp files ---
-rm -f "$TMP_DIR/$PLEX_ARCHIVE" "$TMP_DIR/$TAUTULLI_ARCHIVE"
-
-# --- Sizes ---
-PLEX_ARCHIVE_SIZE=$(ls -lh "$NFS_DEST/$PLEX_LOC/$PLEX_ARCHIVE" 2>/dev/null | awk '{print $5}')
-TAUTULLI_ARCHIVE_SIZE=$(ls -lh "$NFS_DEST/$TAUTULLI_LOC/$TAUTULLI_ARCHIVE" 2>/dev/null | awk '{print $5}')
-NFS_FREE=$(df -h "$NFS_DEST" 2>/dev/null | awk 'NR==2{print $4}')
-PLEX_BACKUP_COUNT=$(ls "$NFS_DEST/$PLEX_LOC"/plex-config-*.tar.gz 2>/dev/null | wc -l)
-TAUTULLI_BACKUP_COUNT=$(ls "$NFS_DEST/$TAUTULLI_LOC"/tautulli-config-*.tar.gz 2>/dev/null | wc -l)
-
-# --- Total duration ---
-END_TIME=$(date +%s)
-TOTAL_DURATION=$((END_TIME - START_TIME))
-TOTAL_MIN=$((TOTAL_DURATION / 60))
-TOTAL_SEC=$((TOTAL_DURATION % 60))
-
-# --- Overall status ---
-PLEX_STATUS=$((PLEX_TAR_STATUS + PLEX_COPY_STATUS))
-TAUTULLI_STATUS=$((TAUTULLI_TAR_STATUS + TAUTULLI_COPY_STATUS))
-
-if [ $PLEX_STATUS -eq 0 ] && [ $TAUTULLI_STATUS -eq 0 ] && [ $START_STATUS -eq 0 ]; then
- OVERALL_STATUS="SUCCESS"
- STATUS_COLOR="#1a7f4b"
- BANNER_ICON="✅"
- BANNER_MSG="Backup completed successfully — Plex and Tautulli configs archived to NAS08"
- BADGE_COLOR="#1a7f4b"
-elif [ $PLEX_STATUS -ne 0 ] && [ $TAUTULLI_STATUS -ne 0 ]; then
- OVERALL_STATUS="FAILED"
- STATUS_COLOR="#b91c1c"
- BANNER_ICON="🔴"
- BANNER_MSG="Backup failed — both archive operations encountered errors"
- BADGE_COLOR="#b91c1c"
-else
- OVERALL_STATUS="PARTIAL"
- STATUS_COLOR="#b45309"
- BANNER_ICON="⚠️"
- BANNER_MSG="Backup partially completed — review individual results below"
- BADGE_COLOR="#b45309"
-fi
-
-# --- Status labels ---
-if [ $PLEX_STATUS -eq 0 ]; then
- PLEX_LABEL="✅ SUCCESS"
- PLEX_ROW_BG="#f0fdf4"
- PLEX_TEXT_COLOR="#166534"
-else
- PLEX_LABEL="❌ FAILED"
- PLEX_ROW_BG="#fff1f2"
- PLEX_TEXT_COLOR="#b91c1c"
-fi
-
-if [ $TAUTULLI_STATUS -eq 0 ]; then
- TAUTULLI_LABEL="✅ SUCCESS"
- TAUTULLI_ROW_BG="#f0fdf4"
- TAUTULLI_TEXT_COLOR="#166534"
-else
- TAUTULLI_LABEL="❌ FAILED"
- TAUTULLI_ROW_BG="#fff1f2"
- TAUTULLI_TEXT_COLOR="#b91c1c"
-fi
-
-if [ $START_STATUS -eq 0 ]; then
- RESTART_LABEL="✅ RUNNING"
- RESTART_COLOR="#166534"
-else
- RESTART_LABEL="❌ CHECK REQUIRED"
- RESTART_COLOR="#b91c1c"
-fi
-
-# --- Send email ---
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Sending email report..."
-
-python3 << PYEOF
-import smtplib, ssl
-from email.mime.multipart import MIMEMultipart
-from email.mime.text import MIMEText
-
-smtp_server = "$SMTP_SERVER"
-smtp_port = $SMTP_PORT
-smtp_user = "$SMTP_USER"
-smtp_pass = "$SMTP_PASS"
-email_to = "$EMAIL_TO"
-email_from = "$EMAIL_FROM"
-
-subject = "PLEX32 Backup — $OVERALL_STATUS — $DATESTAMP"
-
-html = """
-
-
-
-
-
-
-
-
-
-
- |
- Config Backup
- 🎬 plex32
- $TIMESTAMP | VLAN 50 — Lab/Servers
- |
-
- $OVERALL_STATUS
- |
-
- |
-
-
- |
- $BANNER_ICON $BANNER_MSG
- |
-
-
-
-
-
-
-
-
-
- Duration
- ${TOTAL_MIN}m ${TOTAL_SEC}s
-
- |
-
-
- Plex Archive
- $PLEX_ARCHIVE_SIZE
-
- |
-
-
- Tautulli Archive
- $TAUTULLI_ARCHIVE_SIZE
-
- |
-
-
- NAS08 Free
- $NFS_FREE
-
- |
-
-
-
-
-
- 📋 Backup Results
-
-
- | Component |
- Archive |
- Copies Kept |
- Duration |
- Status |
-
-
- | 🎬 Plex Config |
- $PLEX_ARCHIVE |
- $PLEX_BACKUP_COUNT / $RETENTION_COUNT |
- ${PLEX_DURATION}s tar + ${PLEX_COPY_DURATION}s copy |
- $PLEX_LABEL |
-
-
- | 📊 Tautulli Config |
- $TAUTULLI_ARCHIVE |
- $TAUTULLI_BACKUP_COUNT / $RETENTION_COUNT |
- ${TAUTULLI_DURATION}s tar + ${TAUTULLI_COPY_DURATION}s copy |
- $TAUTULLI_LABEL |
-
-
-
-
-
-
- Container Status After Backup
- $RESTART_LABEL
-
-
-
-
- Backup Destination
- NAS08 (192.168.150.35) via NFS — $NFS_FREE free
-
-
-
-
- 💡 To Restore
- tar -xzf $PLEX_ARCHIVE -C /opt/plex
-
-
- |
-
-
- |
- Config Backup | plex32 | KingDezigns Infrastructure
- |
-
-
- |
-
-
-
-"""
-
-msg = MIMEMultipart("alternative")
-msg["Subject"] = subject
-msg["From"] = email_from
-msg["To"] = email_to
-msg.attach(MIMEText(html, "html"))
-
-ctx = ssl.create_default_context()
-with smtplib.SMTP_SSL(smtp_server, smtp_port, context=ctx, timeout=15) as s:
- s.login(smtp_user, smtp_pass)
- s.sendmail(email_from, [email_to], msg.as_string())
-print("Email sent successfully")
-PYEOF
-
-EMAIL_STATUS=$?
-if [ $EMAIL_STATUS -eq 0 ]; then
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] Email sent successfully"
-else
- echo "[ERROR] Email send failed"
-fi
-
-# --- Cleanup old logs ---
-find "$LOG_DIR" -name "backup-*.log" -mtime +$RETENTION_DAYS -delete 2>/dev/null
-
-echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup complete — Status: $OVERALL_STATUS | Duration: ${TOTAL_MIN}m ${TOTAL_SEC}s"
diff --git a/plex32_update_check.sh b/plex32_update_check.sh
index f947572..8fd7a5f 100644
--- a/plex32_update_check.sh
+++ b/plex32_update_check.sh
@@ -71,6 +71,25 @@ fi
echo "[INFO] Plex status: $PLEX_STATUS_TEXT"
+# =============================================================
+# STEP 2B — VERIFY RUNNING CONTAINER (independent of pull result)
+# =============================================================
+echo "[INFO] Checking actual running Plex container..."
+
+CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' plex 2>/dev/null)
+CONTAINER_STARTED=$(docker inspect -f '{{.State.StartedAt}}' plex 2>/dev/null | cut -d'.' -f1 | tr 'T' ' ')
+CONTAINER_HEALTH=$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}n/a{{end}}' plex 2>/dev/null)
+
+if [ "$CONTAINER_STATUS" = "running" ]; then
+ CONTAINER_OK=true
+ CONTAINER_STATUS_TEXT="Running since $CONTAINER_STARTED UTC"
+else
+ CONTAINER_OK=false
+ CONTAINER_STATUS_TEXT="NOT running (status: ${CONTAINER_STATUS:-unknown})"
+fi
+
+echo "[INFO] Plex container status: $CONTAINER_STATUS_TEXT"
+
# =============================================================
# STEP 3 — CHECK FAIL2BAN VERSION
# =============================================================
@@ -115,15 +134,25 @@ ANY_UPDATES=false
[ "$APT_FAILED" = true ] && ANY_FAILED=true
[ "$PLEX_FAILED" = true ] && ANY_FAILED=true
+[ "$CONTAINER_OK" = false ] && ANY_FAILED=true
[ "$APT_UPDATES" -gt 0 ] && ANY_UPDATES=true
[ "$PLEX_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true
[ "$F2B_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true
[ "$DOCKER_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true
-if [ "$ANY_FAILED" = true ]; then
+# 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.
+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="⚠ One or more update checks failed — manual verification required"
+ 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"
@@ -229,6 +258,12 @@ PLEX_BADGE=$(make_badge "$PLEX_UPDATE_AVAILABLE" "$PLEX_FAILED")
F2B_BADGE=$(make_badge "$F2B_UPDATE_AVAILABLE" "false")
DOCKER_BADGE=$(make_badge "$DOCKER_UPDATE_AVAILABLE" "false")
+if [ "$CONTAINER_OK" = true ]; then
+ CONTAINER_BADGE="RUNNING"
+else
+ CONTAINER_BADGE="DOWN"
+fi
+
# =============================================================
# STEP 9 — BUILD & SEND EMAIL
# =============================================================
@@ -249,9 +284,12 @@ subject = "$SUBJECT"
plex_status = "$PLEX_STATUS_TEXT"
f2b_status = "$F2B_STATUS_TEXT"
docker_status = "$DOCKER_STATUS_TEXT"
+container_ok = "$CONTAINER_OK" == "true"
+container_status = "$CONTAINER_STATUS_TEXT"
plex_badge = """$PLEX_BADGE"""
f2b_badge = """$F2B_BADGE"""
docker_badge = """$DOCKER_BADGE"""
+container_badge = """$CONTAINER_BADGE"""
update_commands = """$UPDATE_COMMANDS_HTML"""
apt_packages_html = """$APT_PACKAGES_HTML"""
plex_error_html = """$PLEX_ERROR_HTML"""
@@ -338,6 +376,10 @@ html = f"""
🎬 Plex Media Server {plex_badge} |
{plex_status} Image: {plex_image_ver} | Built: {current_image_date}{plex_error_html} |
+
+ | ✅ Plex Container (actual) {container_badge} |
+ {container_status} This is the real, running-right-now status — independent of the registry check above. |
+
| 🛡 Fail2Ban {f2b_badge} |
{f2b_status} |