#!/bin/bash # Deploy frontend-dapp to VMID 7810 # Builds the frontend and deploys to nginx on Proxmox VM set -euo pipefail # Deployment script for Bridge DApp Frontend (Admin Panel) # Note: VMID 7810 is for mim4u.org - this is a DIFFERENT deployment # Bridge frontend should use a different VMID (specify when running) PROXMOX_HOST="${1:-192.168.11.12}" VMID="${2:-}" # Must be specified - different from mim4u VMID 7810 FRONTEND_APP_PATH="${3:-/home/intlc/projects/proxmox/smom-dbis-138/frontend-dapp}" WEB_ROOT="/var/www/html/bridge-dapp" # Validate VMID is provided if [ -z "$VMID" ]; then log_error "VMID must be specified (VMID 7810 is for mim4u.org, not bridge frontend)" echo "Usage: $0 [proxmox-host] [vmid] [app-path]" echo "Example: $0 192.168.11.12 7811 /home/intlc/projects/proxmox/smom-dbis-138/frontend-dapp" exit 1 fi # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } echo "" log_info "═══════════════════════════════════════════════════════════" log_info " DEPLOYING BRIDGE DAPP FRONTEND TO VMID $VMID" log_info " (Note: VMID 7810 is for mim4u.org - separate deployment)" log_info "═══════════════════════════════════════════════════════════" echo "" # Step 1: Build locally log_info "Step 1: Building production bundle..." cd "$FRONTEND_APP_PATH" if [ ! -f "package.json" ]; then log_error "package.json not found in $FRONTEND_APP_PATH" exit 1 fi # Check if dist exists and is recent if [ -d "dist" ] && [ -f "dist/index.html" ]; then DIST_AGE=$(find dist -name "index.html" -mmin +60 | wc -l) if [ "$DIST_AGE" -eq 0 ]; then log_success "Recent build found in dist/, using existing build" USE_EXISTING_BUILD=true else log_warn "Build is older than 60 minutes, rebuilding..." USE_EXISTING_BUILD=false fi else log_info "No existing build found, building now..." USE_EXISTING_BUILD=false fi if [ "$USE_EXISTING_BUILD" = false ]; then log_info "Running pnpm build (this may take a while)..." pnpm run build || { log_error "Build failed" exit 1 } log_success "Build completed" else log_success "Using existing build" fi if [ ! -f "dist/index.html" ]; then log_error "Build failed: dist/index.html not found" exit 1 fi echo "" # Step 2: Create tarball log_info "Step 2: Creating deployment package..." TEMP_TAR="/tmp/frontend-dapp-$$.tar.gz" cd "$FRONTEND_APP_PATH" tar -czf "$TEMP_TAR" -C dist . || { log_error "Failed to create tarball" exit 1 } TAR_SIZE=$(du -h "$TEMP_TAR" | cut -f1) log_success "Package created: $TAR_SIZE" echo "" # Step 3: Transfer to Proxmox host log_info "Step 3: Transferring to Proxmox host..." scp -o StrictHostKeyChecking=no "$TEMP_TAR" root@"$PROXMOX_HOST":/tmp/ >/dev/null || { log_error "Failed to transfer to Proxmox host" exit 1 } log_success "Transferred to Proxmox host" echo "" # Step 4: Ensure VMID is running log_info "Step 4: Ensuring VMID $VMID is running..." STATUS=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct status $VMID 2>/dev/null | grep -o 'running' || echo 'not-running'") if [ "$STATUS" != "running" ]; then log_info "VMID $VMID is not running, starting it..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct start $VMID" >/dev/null 2>&1 log_info "Waiting for VMID $VMID to start..." sleep 5 for i in {1..30}; do STATUS=$(ssh -o ConnectTimeout=5 root@"$PROXMOX_HOST" "pct status $VMID 2>/dev/null | grep -o 'running' || echo 'not-running'") if [ "$STATUS" = "running" ]; then log_success "VMID $VMID is now running" sleep 3 # Give it a moment to fully initialize break fi sleep 2 done if [ "$STATUS" != "running" ]; then log_error "Failed to start VMID $VMID" exit 1 fi fi # Step 5: Deploy to VMID log_info "Step 5: Deploying to VMID $VMID..." TAR_NAME=$(basename "$TEMP_TAR") # Copy tarball into container ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct push $VMID /tmp/$TAR_NAME /tmp/$TAR_NAME" >/dev/null || { log_error "Failed to push tarball to VMID $VMID (ensure container is running)" exit 1 } # Extract and deploy ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' WEB_ROOT=\"$WEB_ROOT\" TAR_FILE=\"/tmp/$TAR_NAME\" # Create web root directory mkdir -p \"\$WEB_ROOT\" # Extract tarball cd \"\$WEB_ROOT\" tar -xzf \"\$TAR_FILE\" || { echo \"EXTRACT_FAILED\"; exit 1; } # Clean up tarball rm -f \"\$TAR_FILE\" # Set permissions chown -R www-data:www-data \"\$WEB_ROOT\" 2>/dev/null || chown -R nginx:nginx \"\$WEB_ROOT\" 2>/dev/null || true find \"\$WEB_ROOT\" -type d -exec chmod 755 {} \\; find \"\$WEB_ROOT\" -type f -exec chmod 644 {} \\; echo \"DEPLOY_SUCCESS\" '" || { log_error "Failed to deploy to VMID $VMID" exit 1 } log_success "Deployed to $WEB_ROOT" echo "" # Step 6: Deploy nginx configuration log_info "Step 6: Configuring nginx..." # Create nginx config NGINX_CONFIG=$(cat <<'NGINX_EOF' server { listen 80; listen [::]:80; server_name cross-all.defi-oracle.io; root /var/www/html/bridge-dapp; index index.html; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/json; # Cache static assets location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # SPA routing location / { try_files $uri $uri/ /index.html; } # Deny hidden files location ~ /\. { deny all; access_log off; log_not_found off; } } NGINX_EOF ) # Deploy nginx config ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' cat > /etc/nginx/sites-available/bridge-dapp <<'\''NGINX_EOF'\'' $(echo "$NGINX_CONFIG") NGINX_EOF # Create symlink ln -sf /etc/nginx/sites-available/bridge-dapp /etc/nginx/sites-enabled/bridge-dapp 2>/dev/null || true # Remove default site if exists rm -f /etc/nginx/sites-enabled/default # Test nginx config nginx -t 2>&1 '" || { log_warn "Nginx config deployment failed, but files are deployed" } log_success "Nginx configuration updated" echo "" # Step 7: Install and restart nginx log_info "Step 7: Installing nginx (if needed)..." # Check if nginx is installed, install if not ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' if ! which nginx >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq nginx curl >/dev/null 2>&1 fi '" || log_warn "Nginx installation check failed, continuing..." log_info "Restarting nginx..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- systemctl restart nginx" 2>/dev/null || { log_warn "nginx restart failed, attempting reload..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- nginx -s reload" 2>/dev/null || true } sleep 2 if ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- systemctl is-active --quiet nginx" 2>/dev/null; then log_success "nginx is running" else log_warn "nginx status unknown" fi echo "" # Step 8: Verify deployment log_info "Step 8: Verifying deployment..." VM_IP=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct config $VMID | grep -oP 'ip=\K[^/]+' | head -1" 2>/dev/null || echo "192.168.11.37") if ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- test -f $WEB_ROOT/index.html" 2>/dev/null; then FILE_COUNT=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- find $WEB_ROOT -type f | wc -l" 2>/dev/null || echo "0") log_success "Deployment verified: $FILE_COUNT files deployed" # Test HTTP HTTP_CODE=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" \ "pct exec $VMID -- bash -c 'curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 3 http://127.0.0.1/ 2>/dev/null || echo \"000\"'" 2>/dev/null || echo "000") if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "304" ]; then log_success "HTTP test passed (status: $HTTP_CODE)" else log_warn "HTTP test returned status: $HTTP_CODE" fi else log_error "Deployment verification failed: index.html not found" exit 1 fi echo "" # Cleanup rm -f "$TEMP_TAR" ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "rm -f /tmp/$TAR_NAME" 2>/dev/null || true # Summary log_success "═══════════════════════════════════════════════════════════" log_success " DEPLOYMENT COMPLETE" log_success "═══════════════════════════════════════════════════════════" echo "" log_info "Frontend deployed to: VMID $VMID ($WEB_ROOT)" log_info "Access via:" echo " • Direct: http://$VM_IP/" echo " • Domain: https://cross-all.defi-oracle.io/ (via NPMplus)" echo "" log_info "⚠️ Next Steps:" echo " 1. Configure NPMplus proxy host for: cross-all.defi-oracle.io" echo " 2. Point proxy to: http://$VM_IP/" echo " 3. Enable SSL/TLS in NPMplus" echo "" log_info "Nginx config: /etc/nginx/sites-available/bridge-dapp" echo ""