#!/bin/bash # Deploy custom explorer frontend to VMID 5000 # This script copies the frontend to /var/www/html/ and updates nginx set -euo pipefail VMID=5000 VM_IP="192.168.11.140" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" FRONTEND_SOURCE="${REPO_ROOT}/explorer-monorepo/frontend/public/index.html" [ -f "$FRONTEND_SOURCE" ] || FRONTEND_SOURCE="${SCRIPT_DIR}/../frontend/public/index.html" FRONTEND_PUBLIC="$(dirname "$FRONTEND_SOURCE")" PROXMOX_R630_02="${PROXMOX_HOST_R630_02:-192.168.11.12}" echo "==========================================" echo "Deploying Custom Explorer Frontend" echo "==========================================" echo "" # Check if running from Proxmox host or inside container if [ -f "/proc/1/cgroup" ] && grep -q "lxc" /proc/1/cgroup 2>/dev/null; then EXEC_PREFIX="" echo "Running inside VMID 5000" DEPLOY_METHOD="direct" run_in_vm() { "$@"; } elif command -v pct &>/dev/null; then EXEC_PREFIX="pct exec $VMID --" echo "Running from Proxmox host, executing in VMID 5000" DEPLOY_METHOD="pct" run_in_vm() { pct exec $VMID -- "$@"; } else echo "Running from remote: will scp + SSH to $PROXMOX_R630_02 and deploy to VMID $VMID" DEPLOY_METHOD="remote" EXEC_PREFIX="" run_in_vm() { ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${PROXMOX_R630_02} "pct exec $VMID -- $*"; } fi # Step 1: Check if frontend file exists if [ ! -f "$FRONTEND_SOURCE" ]; then echo "❌ Frontend file not found: $FRONTEND_SOURCE" echo "Please ensure you're running from the correct directory" exit 1 fi echo "✅ Frontend source found: $FRONTEND_SOURCE" echo "" # Step 2: Create /var/www/html if it doesn't exist echo "=== Step 2: Preparing deployment directory ===" run_in_vm "mkdir -p /var/www/html" run_in_vm "chown -R www-data:www-data /var/www/html" 2>/dev/null || true echo "✅ Directory prepared" echo "" # Step 3: Backup existing frontend echo "=== Step 3: Backing up existing frontend ===" run_in_vm "bash -c 'if [ -f /var/www/html/index.html ]; then cp /var/www/html/index.html /var/www/html/index.html.backup.\$(date +%Y%m%d_%H%M%S); echo \"✅ Backup created\"; else echo \"⚠️ No existing frontend to backup\"; fi'" echo "" # Step 4: Deploy frontend echo "=== Step 4: Deploying frontend ===" if [ "$DEPLOY_METHOD" = "direct" ]; then # Running inside VMID 5000 cp "$FRONTEND_SOURCE" /var/www/html/index.html chown www-data:www-data /var/www/html/index.html 2>/dev/null || true echo "✅ Frontend deployed" elif [ "$DEPLOY_METHOD" = "remote" ]; then scp -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$FRONTEND_SOURCE" root@${PROXMOX_R630_02}:/tmp/explorer-index.html ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${PROXMOX_R630_02} "pct push $VMID /tmp/explorer-index.html /var/www/html/index.html --perms 0644 && pct exec $VMID -- chown www-data:www-data /var/www/html/index.html" echo "✅ Frontend deployed via $PROXMOX_R630_02" else # Running from Proxmox host pct push $VMID "$FRONTEND_SOURCE" /var/www/html/index.html $EXEC_PREFIX chown www-data:www-data /var/www/html/index.html 2>/dev/null || true echo "✅ Frontend deployed" fi echo "" # Step 4b: Deploy favicon and apple-touch-icon echo "=== Step 4b: Deploying icons ===" for ASSET in explorer-spa.js apple-touch-icon.png favicon.ico; do SRC="${FRONTEND_PUBLIC}/${ASSET}" if [ ! -f "$SRC" ]; then echo "⚠️ Skip $ASSET (not found)" continue fi if [ "$DEPLOY_METHOD" = "direct" ]; then cp "$SRC" "/var/www/html/$ASSET" chown www-data:www-data "/var/www/html/$ASSET" 2>/dev/null || true echo "✅ $ASSET deployed" elif [ "$DEPLOY_METHOD" = "remote" ]; then scp -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$SRC" root@${PROXMOX_R630_02}:/tmp/"$ASSET" ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${PROXMOX_R630_02} "pct push $VMID /tmp/$ASSET /var/www/html/$ASSET --perms 0644 && pct exec $VMID -- chown www-data:www-data /var/www/html/$ASSET" echo "✅ $ASSET deployed via $PROXMOX_R630_02" else pct push $VMID "$SRC" "/var/www/html/$ASSET" $EXEC_PREFIX chown www-data:www-data "/var/www/html/$ASSET" 2>/dev/null || true echo "✅ $ASSET deployed" fi done echo "" # Step 5 (remote): Apply nginx config so /favicon.ico and /apple-touch-icon.png are served if [ "$DEPLOY_METHOD" = "remote" ]; then echo "=== Step 5 (remote): Applying nginx config for icons ===" FIX_NGINX_SCRIPT="${REPO_ROOT}/explorer-monorepo/scripts/fix-nginx-serve-custom-frontend.sh" if [ -f "$FIX_NGINX_SCRIPT" ]; then scp -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$FIX_NGINX_SCRIPT" root@${PROXMOX_R630_02}:/tmp/fix-nginx-explorer.sh ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${PROXMOX_R630_02} "pct push $VMID /tmp/fix-nginx-explorer.sh /tmp/fix-nginx-explorer.sh --perms 0755 && pct exec $VMID -- /tmp/fix-nginx-explorer.sh" echo "✅ Nginx config applied (favicon and apple-touch-icon locations)" else echo "⚠️ Nginx fix script not found ($FIX_NGINX_SCRIPT); icons may still 404 until nginx is updated on VM" fi echo "" fi # Step 5 (local/pct): Update nginx configuration if [ "$DEPLOY_METHOD" != "remote" ]; then echo "=== Step 5: Updating nginx configuration ===" $EXEC_PREFIX bash << 'NGINX_UPDATE' CONFIG_FILE="/etc/nginx/sites-available/blockscout" # Check if config exists if [ ! -f "$CONFIG_FILE" ]; then echo "❌ Nginx config not found: $CONFIG_FILE" exit 1 fi # Update HTTPS server block to serve static files for root, proxy API sed -i '/location \/ {/,/}/c\ # Serve custom frontend for root path\ location = / {\ root /var/www/html;\ try_files /index.html =404;\ }\ \ # Serve static assets\ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {\ root /var/www/html;\ expires 1y;\ add_header Cache-Control "public, immutable";\ }\ \ # Proxy Blockscout UI if needed (fallback)\ location /blockscout/ {\ proxy_pass http://127.0.0.1:4000/;\ proxy_http_version 1.1;\ proxy_set_header Host $host;\ proxy_set_header X-Real-IP $remote_addr;\ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\ proxy_set_header X-Forwarded-Proto $scheme;\ }' "$CONFIG_FILE" echo "✅ Nginx config updated" NGINX_UPDATE # Step 6: Test and restart nginx echo "" echo "=== Step 6: Testing and restarting nginx ===" if $EXEC_PREFIX nginx -t; then echo "✅ Configuration valid" $EXEC_PREFIX systemctl restart nginx echo "✅ Nginx restarted" else echo "❌ Configuration has errors" exit 1 fi echo "" fi # Step 7: Verify deployment echo "=== Step 7: Verifying deployment ===" sleep 2 run_in_vm() { if [ "$DEPLOY_METHOD" = "remote" ]; then ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@${PROXMOX_R630_02} "pct exec $VMID -- $1" else $EXEC_PREFIX $1 fi } # Check if file exists if run_in_vm "test -f /var/www/html/index.html"; then echo "✅ Frontend file exists" # Check if it contains expected content if run_in_vm "grep -q SolaceScanScout /var/www/html/index.html"; then echo "✅ Frontend content verified" else echo "⚠️ Frontend file exists but content may be incorrect" fi else echo "❌ Frontend file not found" exit 1 fi # Test HTTP endpoint (non-fatal: do not exit on failure) HTTP_RESPONSE=$(run_in_vm "curl -s --max-time 5 http://localhost/ 2>/dev/null | head -5" 2>/dev/null) || true if echo "$HTTP_RESPONSE" | grep -q "SolaceScanScout\|