Z User commited on
Commit
7bfa1b4
·
1 Parent(s): 85fa724

feat: auto-update hermes-web-ui at runtime

Browse files

- start.sh: update_webui_background() runs async after startup
- Queries GitHub API for latest release tag
- Compares with saved version in /data/hermes/webui.version
- If newer: clone → npm install → npm build → hot-swap → restart
- Build failure does NOT affect running instance (temp dir)
- Health check after update to verify new version works
- Dockerfile: write /app/webui.version for initial version tracking
- Set WEBUI_AUTO_UPDATE=false to disable

Files changed (2) hide show
  1. Dockerfile +1 -4
  2. start.sh +132 -0
Dockerfile CHANGED
@@ -75,11 +75,8 @@ RUN rm -rf /tmp/hermes-web-ui && \
75
  npm prune --omit=dev --prefix /tmp/hermes-web-ui 2>&1 | tail -3 && \
76
  cp -r node_modules /app/webui-server/node_modules && \
77
  rm -rf /tmp/hermes-web-ui && \
78
- <<<<<<< HEAD
79
- echo "hermes-web-ui v0.5.3 build done"
80
- =======
81
  echo "hermes-web-ui v0.5.5 build done"
82
- >>>>>>> 0ef21e4 (chore: upgrade hermes-web-ui to v0.5.5)
83
 
84
  # Create hermes home
85
  RUN mkdir -p /root/.hermes/plugins/image_gen/pollinations
 
75
  npm prune --omit=dev --prefix /tmp/hermes-web-ui 2>&1 | tail -3 && \
76
  cp -r node_modules /app/webui-server/node_modules && \
77
  rm -rf /tmp/hermes-web-ui && \
78
+ echo "v0.5.5" > /app/webui.version && \
 
 
79
  echo "hermes-web-ui v0.5.5 build done"
 
80
 
81
  # Create hermes home
82
  RUN mkdir -p /root/.hermes/plugins/image_gen/pollinations
start.sh CHANGED
@@ -444,6 +444,134 @@ for i in $(seq 1 60); do
444
  sleep 2
445
  done
446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  # ── Start hermes-web-ui Node.js BFF server on :6060 ──
448
  echo "[$(date)] Starting hermes-web-ui BFF..."
449
  export PORT=6060
@@ -457,6 +585,10 @@ node index.js >> /data/hermes/logs/webui.log 2>&1 &
457
  WEBUI_PID=$!
458
  echo "[$(date)] WebUI BFF PID: $WEBUI_PID"
459
 
 
 
 
 
460
  # Wait for WebUI BFF to be ready
461
  echo "[$(date)] Waiting for WebUI BFF to start..."
462
  for i in $(seq 1 15); do
 
444
  sleep 2
445
  done
446
 
447
+ # ── Auto-update hermes-web-ui if newer release exists ──
448
+ # Runs asynchronously so it doesn't block startup.
449
+ # Check: GitHub releases/latest → compare with saved version → build if newer.
450
+ # Set WEBUI_AUTO_UPDATE=false to disable.
451
+ update_webui_background() {
452
+ [ "${WEBUI_AUTO_UPDATE}" = "false" ] && return
453
+
454
+ WEBUI_REPO="EKKOLearnAI/hermes-web-ui"
455
+ VERSION_FILE="/data/hermes/webui.version"
456
+ BUILD_TMP="/tmp/webui-update"
457
+ WEBUI_INSTALL="/app/webui-server"
458
+ WEBUI_CLIENT="/app/webui-client"
459
+ API_URL="https://api.github.com/repos/${WEBUI_REPO}/releases/latest"
460
+
461
+ # Current installed version (from Dockerfile build or previous update)
462
+ CURRENT_VERSION="$(cat "$VERSION_FILE" 2>/dev/null | head -1)"
463
+ if [ -z "$CURRENT_VERSION" ]; then
464
+ CURRENT_VERSION="v0.5.5" # fallback to last known build
465
+ echo "$CURRENT_VERSION" > "$VERSION_FILE"
466
+ fi
467
+
468
+ echo "[$(date)] WebUI auto-update: checking for new version (current: $CURRENT_VERSION)..."
469
+
470
+ # Query GitHub API for latest release tag
471
+ LATEST_JSON=$(curl -sf --connect-timeout 10 --max-time 20 "$API_URL" 2>/dev/null)
472
+ if [ $? -ne 0 ] || [ -z "$LATEST_JSON" ]; then
473
+ echo "[$(date)] WebUI auto-update: failed to reach GitHub API, skipping"
474
+ return
475
+ fi
476
+
477
+ LATEST_TAG=$(echo "$LATEST_JSON" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tag_name',''))" 2>/dev/null)
478
+ if [ -z "$LATEST_TAG" ]; then
479
+ echo "[$(date)] WebUI auto-update: could not parse latest tag, skipping"
480
+ return
481
+ fi
482
+
483
+ echo "[$(date)] WebUI auto-update: latest release is $LATEST_TAG"
484
+
485
+ # Compare versions (strip leading 'v' for comparison)
486
+ CURRENT_NUM="${CURRENT_VERSION#v}"
487
+ LATEST_NUM="${LATEST_TAG#v}"
488
+
489
+ # Skip if same or current is newer
490
+ if [ "$CURRENT_NUM" = "$LATEST_NUM" ]; then
491
+ echo "[$(date)] WebUI auto-update: already on latest ($CURRENT_VERSION)"
492
+ return
493
+ fi
494
+
495
+ # Simple version comparison: split by dots and compare
496
+ update_needed=false
497
+ IFS='.' read -ra C <<< "$CURRENT_NUM"
498
+ IFS='.' read -ra L <<< "$LATEST_NUM"
499
+ for i in 0 1 2; do
500
+ c=${C[$i]:-0}; l=${L[$i]:-0}
501
+ if [ "$l" -gt "$c" ] 2>/dev/null; then
502
+ update_needed=true; break
503
+ elif [ "$l" -lt "$c" ] 2>/dev/null; then
504
+ break
505
+ fi
506
+ done
507
+
508
+ if [ "$update_needed" = "false" ]; then
509
+ echo "[$(date)] WebUI auto-update: current $CURRENT_VERSION is up to date"
510
+ return
511
+ fi
512
+
513
+ echo "[$(date)] WebUI auto-update: upgrading $CURRENT_VERSION → $LATEST_TAG ..."
514
+
515
+ # Build in temp directory
516
+ rm -rf "$BUILD_TMP"
517
+ if ! git clone --depth 1 --branch "$LATEST_TAG" "https://github.com/${WEBUI_REPO}.git" "$BUILD_TMP" 2>&1 | tail -3; then
518
+ echo "[$(date)] WebUI auto-update: git clone failed, aborting"
519
+ rm -rf "$BUILD_TMP"
520
+ return
521
+ fi
522
+
523
+ cd "$BUILD_TMP"
524
+ if ! npm install --ignore-scripts 2>&1 | tail -5; then
525
+ echo "[$(date)] WebUI auto-update: npm install failed, aborting"
526
+ rm -rf "$BUILD_TMP"
527
+ return
528
+ fi
529
+
530
+ if ! npm run build 2>&1 | tail -10; then
531
+ echo "[$(date)] WebUI auto-update: npm build failed, aborting"
532
+ rm -rf "$BUILD_TMP"
533
+ return
534
+ fi
535
+
536
+ # Verify build output exists
537
+ if [ ! -d "$BUILD_TMP/dist/server" ] || [ ! -d "$BUILD_TMP/dist/client" ]; then
538
+ echo "[$(date)] WebUI auto-update: build output missing, aborting"
539
+ rm -rf "$BUILD_TMP"
540
+ return
541
+ fi
542
+
543
+ # Hot-swap: kill old WebUI process, replace files, restart
544
+ echo "[$(date)] WebUI auto-update: replacing files and restarting BFF..."
545
+ OLD_WEBUI_PID=$(pgrep -f "node index.js" 2>/dev/null | head -1)
546
+ [ -n "$OLD_WEBUI_PID" ] && kill "$OLD_WEBUI_PID" 2>/dev/null && sleep 1
547
+
548
+ # Backup old, install new
549
+ cp -r "$BUILD_TMP/dist/server/"* "$WEBUI_INSTALL/" 2>/dev/null
550
+ cp -r "$BUILD_TMP/dist/client/"* "$WEBUI_CLIENT/" 2>/dev/null
551
+ cp "$BUILD_TMP/package.json" "$WEBUI_INSTALL/package.json"
552
+ cp -rn "$BUILD_TMP/node_modules/"* "$WEBUI_INSTALL/node_modules/" 2>/dev/null
553
+
554
+ # Save new version
555
+ echo "$LATEST_TAG" > "$VERSION_FILE"
556
+ echo "$(date '+%Y-%m-%d %H:%M:%S')" >> "$VERSION_FILE"
557
+
558
+ # Restart WebUI
559
+ cd "$WEBUI_INSTALL"
560
+ node index.js >> /data/hermes/logs/webui.log 2>&1 &
561
+ NEW_PID=$!
562
+ echo "[$(date)] WebUI auto-update: upgraded to $LATEST_TAG (new PID: $NEW_PID)"
563
+
564
+ # Verify
565
+ sleep 3
566
+ if curl -s http://127.0.0.1:6060/health > /dev/null 2>&1; then
567
+ echo "[$(date)] WebUI auto-update: $LATEST_TAG is running and healthy ✓"
568
+ else
569
+ echo "[$(date)] WebUI auto-update: WARNING - new version health check failed"
570
+ fi
571
+
572
+ rm -rf "$BUILD_TMP"
573
+ }
574
+
575
  # ── Start hermes-web-ui Node.js BFF server on :6060 ──
576
  echo "[$(date)] Starting hermes-web-ui BFF..."
577
  export PORT=6060
 
585
  WEBUI_PID=$!
586
  echo "[$(date)] WebUI BFF PID: $WEBUI_PID"
587
 
588
+ # Trigger WebUI auto-update in background (non-blocking)
589
+ # Will check GitHub, build if newer, and hot-swap
590
+ update_webui_background &
591
+
592
  # Wait for WebUI BFF to be ready
593
  echo "[$(date)] Waiting for WebUI BFF to start..."
594
  for i in $(seq 1 15); do