Files
explorer-monorepo/scripts/fix-explorer-complete.sh

424 lines
13 KiB
Bash
Raw Permalink Normal View History

#!/bin/bash
# Complete fix for explorer.d-bis.org
# This script fixes the explorer by deploying the static frontend and ensuring nginx is properly configured
# Can be run from Proxmox host or inside VMID 5000
set -euo pipefail
VMID=5000
VM_IP="192.168.11.140"
FRONTEND_SOURCE="/home/intlc/projects/proxmox/explorer-monorepo/frontend/public/index.html"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Detect if running inside container or from Proxmox host
if [ -f "/proc/1/cgroup" ] && grep -q "lxc" /proc/1/cgroup 2>/dev/null; then
EXEC_PREFIX=""
IS_CONTAINER=true
echo "Detected: Running inside LXC container"
else
EXEC_PREFIX="pct exec $VMID --"
IS_CONTAINER=false
echo "Detected: Running from Proxmox host"
# Check if VMID 5000 exists
if ! pct list | grep -q "^$VMID "; then
echo "❌ VMID $VMID not found!"
echo "Attempting to deploy static server locally..."
IS_CONTAINER=false
NO_VMID=true
else
NO_VMID=false
fi
fi
echo "=========================================="
echo "Complete Explorer Fix"
echo "=========================================="
echo "Frontend Source: $FRONTEND_SOURCE"
echo "=========================================="
echo ""
# Step 1: Verify frontend file exists
echo "=== Step 1: Verifying frontend file ==="
if [ ! -f "$FRONTEND_SOURCE" ]; then
echo "❌ Frontend file not found: $FRONTEND_SOURCE"
echo "Attempting to find frontend file..."
# Try alternate locations
ALTERNATE_LOCATIONS=(
"$REPO_ROOT/explorer-monorepo/frontend/public/index.html"
"$HOME/projects/proxmox/explorer-monorepo/frontend/public/index.html"
"./frontend/public/index.html"
"../frontend/public/index.html"
)
FOUND=false
for loc in "${ALTERNATE_LOCATIONS[@]}"; do
if [ -f "$loc" ]; then
FRONTEND_SOURCE="$loc"
echo "✅ Found frontend at: $FRONTEND_SOURCE"
FOUND=true
break
fi
done
if [ "$FOUND" = false ]; then
echo "❌ Could not find frontend file!"
exit 1
fi
else
echo "✅ Frontend file found: $FRONTEND_SOURCE"
fi
echo ""
# Function to deploy to VMID 5000
deploy_to_vmid() {
echo "=== Deploying to VMID $VMID ==="
# Create directory
$EXEC_PREFIX mkdir -p /var/www/html
$EXEC_PREFIX chown -R www-data:www-data /var/www/html 2>/dev/null || true
# Backup existing
$EXEC_PREFIX bash << 'BACKUP'
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) 2>/dev/null || true
fi
BACKUP
# Deploy frontend
if [ "$IS_CONTAINER" = true ]; then
cp "$FRONTEND_SOURCE" /var/www/html/index.html
chown www-data:www-data /var/www/html/index.html
else
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
fi
echo "✅ Frontend deployed to /var/www/html/index.html"
# Update nginx configuration
update_nginx_config
}
# Function to update nginx configuration
update_nginx_config() {
echo ""
echo "=== Updating nginx configuration ==="
# Check if nginx config exists
NGINX_CONFIG="/etc/nginx/sites-available/blockscout"
if ! $EXEC_PREFIX test -f "$NGINX_CONFIG" 2>/dev/null; then
echo "⚠️ Nginx config not found at $NGINX_CONFIG, creating new config..."
create_nginx_config
return
fi
# Backup config
$EXEC_PREFIX cp "$NGINX_CONFIG" "${NGINX_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
# Update config to serve static frontend
$EXEC_PREFIX bash << 'NGINX_UPDATE'
CONFIG_FILE="/etc/nginx/sites-available/blockscout"
# Check if root location already serves static files
if ! grep -q "root /var/www/html" "$CONFIG_FILE"; then
# Update HTTPS server block
sed -i '/listen 443/,/^}/ {
/location = \/ {/,/^ }/ {
s|try_files.*|try_files /index.html =404;|
}
/location \/ {/ {
/proxy_pass/,/^ }/ {
s|proxy_pass.*|root /var/www/html;|
s|proxy_http_version.*||
s|proxy_set_header.*||
s|proxy_read_timeout.*||
/proxy_/d
}
}
}' "$CONFIG_FILE"
# Ensure root location serves static files
if ! grep -q "location = / {" "$CONFIG_FILE"; then
# Add location block after server_name
sed -i '/server_name/a\
# Serve custom frontend for root path\
location = / {\
root /var/www/html;\
try_files /index.html =404;\
}' "$CONFIG_FILE"
fi
echo "✅ Nginx config updated"
else
echo "✅ Nginx already configured to serve static files"
fi
# Test and reload nginx
if nginx -t 2>/dev/null; then
systemctl reload nginx 2>/dev/null || systemctl restart nginx 2>/dev/null || true
echo "✅ Nginx reloaded"
else
echo "⚠️ Nginx config test failed, skipping reload"
nginx -t 2>&1 || true
fi
NGINX_UPDATE
}
# Function to create new nginx config
create_nginx_config() {
$EXEC_PREFIX bash << 'CREATE_NGINX'
cat > /etc/nginx/sites-available/blockscout << 'NGINX_EOF'
# HTTP server - redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name explorer.d-bis.org 192.168.11.140;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# API endpoint - proxy to Blockscout if available
location /api/ {
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;
add_header Access-Control-Allow-Origin *;
}
# Serve static frontend
location = / {
root /var/www/html;
try_files /index.html =404;
}
# All other requests redirect to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name explorer.d-bis.org 192.168.11.140;
# SSL configuration (optional - Cloudflare may handle SSL)
# ssl_certificate /etc/letsencrypt/live/explorer.d-bis.org/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/explorer.d-bis.org/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
access_log /var/log/nginx/blockscout-access.log;
error_log /var/log/nginx/blockscout-error.log;
# 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";
}
# API endpoint - proxy to Blockscout if available
location /api/ {
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;
proxy_read_timeout 300s;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";
}
}
NGINX_EOF
# Enable site
ln -sf /etc/nginx/sites-available/blockscout /etc/nginx/sites-enabled/blockscout 2>/dev/null || true
# Test and reload
if nginx -t 2>/dev/null; then
systemctl reload nginx 2>/dev/null || systemctl restart nginx 2>/dev/null || true
echo "✅ Nginx config created and reloaded"
else
echo "⚠️ Nginx config test failed"
nginx -t 2>&1 || true
fi
CREATE_NGINX
}
# Function to start/check nginx
ensure_nginx_running() {
echo ""
echo "=== Ensuring nginx is running ==="
if $EXEC_PREFIX systemctl is-active nginx >/dev/null 2>&1; then
echo "✅ Nginx is running"
else
echo "⚠️ Nginx is not running, starting..."
$EXEC_PREFIX systemctl start nginx 2>/dev/null || true
sleep 2
if $EXEC_PREFIX systemctl is-active nginx >/dev/null 2>&1; then
echo "✅ Nginx started"
else
echo "❌ Failed to start nginx"
echo "Check logs: $EXEC_PREFIX journalctl -u nginx -n 20"
fi
fi
}
# Function for local server (fallback) - must be defined before use
create_local_server() {
echo "Creating local server option..."
cat > "$REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh" << 'LOCAL_SERVER'
#!/bin/bash
# Simple local server for explorer (fallback option)
# Usage: ./serve-explorer-local.sh [port]
PORT=${1:-8080}
FRONTEND_DIR="$(cd "$(dirname "$0")/../frontend/public" && pwd)"
if [ ! -f "$FRONTEND_DIR/index.html" ]; then
echo "❌ Frontend not found at: $FRONTEND_DIR/index.html"
exit 1
fi
echo "Serving explorer on http://localhost:$PORT"
echo "Frontend: $FRONTEND_DIR"
cd "$FRONTEND_DIR"
# Try Python 3 first, then Python 2
if command -v python3 >/dev/null 2>&1; then
python3 -m http.server "$PORT"
elif command -v python >/dev/null 2>&1; then
python -m SimpleHTTPServer "$PORT"
else
echo "❌ Python not found. Install Python to use this script."
exit 1
fi
LOCAL_SERVER
chmod +x "$REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh"
echo "✅ Local server script created: $REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh"
}
# Main deployment
if [ "${NO_VMID:-false}" != "true" ] && [ "$IS_CONTAINER" = false ]; then
# Deploy to VMID 5000
deploy_to_vmid
ensure_nginx_running
else
# Local deployment or container
if [ "$IS_CONTAINER" = true ]; then
# Running inside container
echo "=== Deploying inside container ==="
mkdir -p /var/www/html
cp "$FRONTEND_SOURCE" /var/www/html/index.html
chown www-data:www-data /var/www/html/index.html 2>/dev/null || true
update_nginx_config
ensure_nginx_running
else
# Local fallback - create simple HTTP server script
echo "⚠️ VMID 5000 not accessible, creating local deployment option"
create_local_server
fi
fi
# Function for local server (fallback) - must be defined before use
create_local_server() {
echo "Creating local server option..."
cat > "$REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh" << 'LOCAL_SERVER'
#!/bin/bash
# Simple local server for explorer (fallback option)
# Usage: ./serve-explorer-local.sh [port]
PORT=${1:-8080}
FRONTEND_DIR="$(cd "$(dirname "$0")/../frontend/public" && pwd)"
if [ ! -f "$FRONTEND_DIR/index.html" ]; then
echo "❌ Frontend not found at: $FRONTEND_DIR/index.html"
exit 1
fi
echo "Serving explorer on http://localhost:$PORT"
echo "Frontend: $FRONTEND_DIR"
cd "$FRONTEND_DIR"
# Try Python 3 first, then Python 2
if command -v python3 >/dev/null 2>&1; then
python3 -m http.server "$PORT"
elif command -v python >/dev/null 2>&1; then
python -m SimpleHTTPServer "$PORT"
else
echo "❌ Python not found. Install Python to use this script."
exit 1
fi
LOCAL_SERVER
chmod +x "$REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh"
echo "✅ Local server script created: $REPO_ROOT/explorer-monorepo/scripts/serve-explorer-local.sh"
}
# Final verification
echo ""
echo "=== Verification ==="
if [ "${NO_VMID:-false}" != "true" ] && [ "$IS_CONTAINER" = false ]; then
# Check if file exists
if $EXEC_PREFIX test -f /var/www/html/index.html; then
echo "✅ Frontend file deployed: /var/www/html/index.html"
else
echo "❌ Frontend file not found"
fi
# Test HTTP endpoint
HTTP_TEST=$($EXEC_PREFIX curl -s -o /dev/null -w '%{http_code}' --connect-timeout 3 http://localhost/ 2>/dev/null || echo "000")
if [ "$HTTP_TEST" = "200" ]; then
echo "✅ HTTP endpoint responding (200)"
else
echo "⚠️ HTTP endpoint returned: $HTTP_TEST"
fi
elif [ "$IS_CONTAINER" = true ]; then
if [ -f /var/www/html/index.html ]; then
echo "✅ Frontend file deployed: /var/www/html/index.html"
HTTP_TEST=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 3 http://localhost/ 2>/dev/null || echo "000")
if [ "$HTTP_TEST" = "200" ]; then
echo "✅ HTTP endpoint responding (200)"
else
echo "⚠️ HTTP endpoint returned: $HTTP_TEST"
fi
fi
fi
echo ""
echo "=========================================="
echo "Fix Complete"
echo "=========================================="
echo ""
echo "Next steps:"
echo "1. Verify explorer is accessible: curl -I https://explorer.d-bis.org"
echo "2. Check nginx logs if issues persist: tail -f /var/log/nginx/blockscout-error.log"
echo "3. Ensure Cloudflare tunnel is running if using Cloudflare"
echo ""