#!/bin/bash # Deploy mim4u.org frontend to VMID 7810 # Builds the frontend and deploys to /var/www/html set -euo pipefail # Load IP configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true PROXMOX_HOST="${1:-192.168.11.12}" VMID="${2:-7810}" MIM_PROJECT_PATH="${3:-/home/intlc/projects/proxmox/miracles_in_motion}" WEB_ROOT="/var/www/html" # 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 MIM4U.ORG FRONTEND TO VMID $VMID" log_info "═══════════════════════════════════════════════════════════" echo "" # Step 1: Check if local dist exists log_info "Step 1: Checking for existing build..." if [ -d "$MIM_PROJECT_PATH/dist" ] && [ -f "$MIM_PROJECT_PATH/dist/index.html" ]; then log_success "Found existing build in $MIM_PROJECT_PATH/dist" USE_EXISTING_BUILD=true else log_warn "No existing build found, will build on VMID $VMID" USE_EXISTING_BUILD=false fi echo "" # Step 2: Prepare VMID 7810 for deployment log_info "Step 2: Preparing VMID $VMID for deployment..." # Install Node.js if not present log_info "Checking Node.js installation..." NODE_VERSION_CHECK=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c 'which node >/dev/null 2>&1 && node --version 2>/dev/null | cut -d. -f1 | sed s/v// || echo 0'" 2>/dev/null || echo "0") if [ "$NODE_VERSION_CHECK" = "0" ] || [ "$NODE_VERSION_CHECK" -lt 18 ]; then log_info "Installing prerequisites (curl, ca-certificates)..." ssh -o ConnectTimeout=30 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq curl ca-certificates gnupg '" 2>&1 | tail -5 || true log_info "Installing Node.js 18 from NodeSource..." ssh -o ConnectTimeout=60 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' export DEBIAN_FRONTEND=noninteractive # Remove old nodejs package if present apt-get remove -y nodejs nodejs-doc libnode72 2>&1 | grep -v \"not installed\" || true # Install NodeSource Node.js 18 curl -fsSL https://deb.nodesource.com/setup_18.x | bash - apt-get install -y nodejs '" 2>&1 | tail -20 || { log_error "Failed to install Node.js" exit 1 } # Verify installation NEW_NODE_VERSION=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- node --version 2>/dev/null" || echo "") if [ -n "$NEW_NODE_VERSION" ]; then log_success "Node.js installed: $NEW_NODE_VERSION" else log_error "Node.js installation verification failed" exit 1 fi else log_success "Node.js already installed (v$NODE_VERSION_CHECK+)" fi # Verify Node.js version NODE_VERSION=$(ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- node --version" 2>/dev/null || echo "") log_info "Node.js version: $NODE_VERSION" echo "" # Step 3: Deploy source or build if [ "$USE_EXISTING_BUILD" = true ]; then # Step 3a: Copy dist folder directly log_info "Step 3: Copying build files to VMID $VMID..." # Create temporary tarball TEMP_TAR="/tmp/mim4u-frontend-$$.tar.gz" log_info "Creating archive of dist folder..." cd "$MIM_PROJECT_PATH" tar -czf "$TEMP_TAR" -C dist . # Copy to Proxmox host log_info "Transferring archive to Proxmox host..." scp -o StrictHostKeyChecking=no "$TEMP_TAR" root@"$PROXMOX_HOST":/tmp/ >/dev/null # Extract to container log_info "Extracting to VMID $VMID web root..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct push $VMID /tmp/$(basename $TEMP_TAR) /tmp/$(basename $TEMP_TAR)" >/dev/null ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' mkdir -p $WEB_ROOT cd $WEB_ROOT tar -xzf /tmp/$(basename '$TEMP_TAR') rm /tmp/$(basename '$TEMP_TAR') chown -R www-data:www-data $WEB_ROOT 2>/dev/null || true '" # Cleanup rm -f "$TEMP_TAR" ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "rm -f /tmp/$(basename $TEMP_TAR)" 2>/dev/null || true log_success "Build files deployed to $WEB_ROOT" else # Step 3b: Copy source and build on VM log_info "Step 3: Copying source code and building on VMID $VMID..." # Create tarball of source (excluding node_modules and dist) TEMP_TAR="/tmp/mim4u-source-$$.tar.gz" log_info "Creating source archive..." cd "$MIM_PROJECT_PATH" tar --exclude='node_modules' \ --exclude='dist' \ --exclude='.git' \ --exclude='*.log' \ -czf "$TEMP_TAR" . # Copy to Proxmox host TAR_NAME=$(basename "$TEMP_TAR") log_info "Transferring source to Proxmox host..." scp -o StrictHostKeyChecking=no "$TEMP_TAR" root@"$PROXMOX_HOST":/tmp/ >/dev/null # Extract and build in container log_info "Extracting source and building in VMID $VMID..." BUILD_DIR="/tmp/mim4u-build-$$" ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct push $VMID /tmp/$TAR_NAME /tmp/$TAR_NAME" >/dev/null ssh -o ConnectTimeout=60 root@"$PROXMOX_HOST" "pct exec $VMID -- bash -c ' BUILD_DIR=\"$BUILD_DIR\" TAR_FILE=\"/tmp/$TAR_NAME\" WEB_ROOT=\"$WEB_ROOT\" mkdir -p \"\$BUILD_DIR\" cd \"\$BUILD_DIR\" echo \"Extracting source archive...\" tar -xzf \"\$TAR_FILE\" || { echo \"TAR_EXTRACT_FAILED\"; exit 1; } rm -f \"\$TAR_FILE\" echo \"Installing dependencies...\" export DEBIAN_FRONTEND=noninteractive npm install --legacy-peer-deps 2>&1 | tail -20 || { echo \"NPM_INSTALL_FAILED\"; exit 1; } echo \"Building application...\" (npm run build 2>&1 || npx vite build 2>&1) | tail -30 if [ -d dist ] && [ -f dist/index.html ]; then mkdir -p \"\$WEB_ROOT\" cp -r dist/* \"\$WEB_ROOT\"/ chown -R www-data:www-data \"\$WEB_ROOT\" 2>/dev/null || true rm -rf \"\$BUILD_DIR\" echo \"BUILD_SUCCESS\" else echo \"BUILD_FAILED - dist/index.html not found\" exit 1 fi '" 2>&1 # Cleanup rm -f "$TEMP_TAR" ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "rm -f /tmp/$(basename $TEMP_TAR)" 2>/dev/null || true log_success "Source built and deployed to $WEB_ROOT" fi echo "" # Step 4: Verify deployment log_info "Step 4: Verifying deployment..." 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 in $WEB_ROOT" ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- ls -lh $WEB_ROOT/index.html" 2>/dev/null | head -1 else log_error "Deployment failed: index.html not found" exit 1 fi echo "" # Step 5: Restart nginx log_info "Step 5: Restarting nginx..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- systemctl restart nginx" 2>/dev/null || { log_warn "nginx restart failed, checking status..." ssh -o ConnectTimeout=10 root@"$PROXMOX_HOST" "pct exec $VMID -- systemctl status nginx | head -5" 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 may not be running" fi echo "" # Step 6: Test HTTP response log_info "Step 6: Testing HTTP response..." 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 echo "" # 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://${IP_MIM_WEB:-192.168.11.37}/" echo " • Public: https://mim4u.org/ (via NPMplus)" echo ""