147 lines
4.9 KiB
Bash
Executable file
147 lines
4.9 KiB
Bash
Executable file
#!/bin/bash
|
|
# ===========================================
|
|
# Enterprise AI Hub Nexus — Deploy Script
|
|
# Run from: /opt/enterprise-ai-hub-nexus/
|
|
# Run as your normal user (NOT sudo)
|
|
# ===========================================
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
COMPOSE_FILE="docker-compose.prod.yml"
|
|
WEB_DIR="/var/www/html/enterprise-ai-hub-nexus"
|
|
FRONTEND_DIR="frontend"
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log() { echo -e "${GREEN}[DEPLOY]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
err() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
|
|
|
|
# Abort if running as root
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
err "Do NOT run with sudo. Run as your normal user: ./deploy.sh"
|
|
fi
|
|
|
|
echo "=== Enterprise AI Hub Nexus Deployment ==="
|
|
echo "Working directory: $SCRIPT_DIR"
|
|
|
|
# -------------------------------------------
|
|
# Prerequisites
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "Checking prerequisites..."
|
|
for cmd in git node npm docker; do
|
|
command -v "$cmd" &>/dev/null && echo " ✓ $cmd" || err "$cmd is not installed"
|
|
done
|
|
|
|
# Check .env exists
|
|
[ -f .env ] || err ".env not found — copy .env.example and fill in values"
|
|
echo " ✓ .env found"
|
|
|
|
# -------------------------------------------
|
|
# 1. Pull latest code
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[1/6] Pulling latest code..."
|
|
git pull --ff-only || err "git pull failed — resolve conflicts first"
|
|
|
|
# -------------------------------------------
|
|
# 2. Build Docker images
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[2/6] Building Docker images..."
|
|
sudo docker compose -f "$COMPOSE_FILE" build
|
|
|
|
# -------------------------------------------
|
|
# 3. Start DB + wait for ready, then run migrations
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[3/6] Starting database and running migrations..."
|
|
|
|
sudo docker compose -f "$COMPOSE_FILE" up -d db redis qdrant
|
|
|
|
echo " Waiting for PostgreSQL to be ready..."
|
|
for i in {1..30}; do
|
|
if sudo docker compose -f "$COMPOSE_FILE" exec -T db \
|
|
pg_isready -U "${POSTGRES_USER:-nexus_user}" -d "${POSTGRES_DB:-nexus_db}" > /dev/null 2>&1; then
|
|
echo " ✓ PostgreSQL is ready"
|
|
break
|
|
fi
|
|
[ "$i" -eq 30 ] && { sudo docker compose -f "$COMPOSE_FILE" logs db | tail -20; err "PostgreSQL failed to start"; }
|
|
sleep 1
|
|
done
|
|
|
|
echo " Running Alembic migrations..."
|
|
if sudo docker compose -f "$COMPOSE_FILE" run --rm -e PYTHONPATH=/app backend alembic upgrade head; then
|
|
log "Migrations complete"
|
|
else
|
|
err "Migrations FAILED — aborting deployment"
|
|
fi
|
|
|
|
# -------------------------------------------
|
|
# 4. Start all services
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[4/6] Starting all services..."
|
|
sudo docker compose -f "$COMPOSE_FILE" up -d --remove-orphans
|
|
|
|
# -------------------------------------------
|
|
# 5. Wait for backend healthy
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[5/6] Waiting for backend to become healthy..."
|
|
for i in {1..30}; do
|
|
if curl -sf "http://127.0.0.1:1222/api/v1/health/live" > /dev/null 2>&1; then
|
|
log "Backend is healthy!"
|
|
break
|
|
fi
|
|
[ "$i" -eq 30 ] && warn "Backend health check timed out — check logs: sudo docker compose -f $COMPOSE_FILE logs backend"
|
|
sleep 2
|
|
done
|
|
|
|
# -------------------------------------------
|
|
# 6. Build and deploy frontend
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "[6/6] Building frontend..."
|
|
cd "$FRONTEND_DIR"
|
|
npm ci --prefer-offline
|
|
|
|
NEXT_PUBLIC_API_URL="https://ai-sandbox.oliver.solutions/nexus/api/v1" \
|
|
NEXT_PUBLIC_ENTRA_TENANT_ID="e519c2e6-bc6d-4fdf-8d9c-923c2f002385" \
|
|
NEXT_PUBLIC_ENTRA_CLIENT_ID="9079054c-9620-4757-a256-23413042f1ef" \
|
|
NEXT_PUBLIC_ENTRA_REDIRECT_URI="https://ai-sandbox.oliver.solutions/nexus" \
|
|
npm run build
|
|
|
|
cd "$SCRIPT_DIR"
|
|
|
|
log "Deploying frontend to ${WEB_DIR}..."
|
|
sudo rm -rf "${WEB_DIR:?}"/*
|
|
sudo cp -r "${FRONTEND_DIR}/out/"* "$WEB_DIR/"
|
|
|
|
# -------------------------------------------
|
|
# Summary
|
|
# -------------------------------------------
|
|
echo ""
|
|
log "========================================="
|
|
log " Deployment complete!"
|
|
log "========================================="
|
|
echo ""
|
|
sudo docker compose -f "$COMPOSE_FILE" ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
|
|
echo ""
|
|
log "Backend: https://ai-sandbox.oliver.solutions/nexus/api/v1/health/live"
|
|
log "Frontend: https://ai-sandbox.oliver.solutions/nexus/"
|
|
log "Code Interpreter dashboard: https://ai-sandbox.oliver.solutions/nexus-code-interpreter/admin-dashboard"
|
|
log ""
|
|
log "NOTE: Apache must proxy /nexus-code-interpreter/ -> http://localhost:8877/"
|
|
log " Add to your Apache VirtualHost config:"
|
|
log " ProxyPass /nexus-code-interpreter/ http://localhost:8877/"
|
|
log " ProxyPassReverse /nexus-code-interpreter/ http://localhost:8877/"
|
|
echo ""
|
|
echo "Migration status:"
|
|
sudo docker compose -f "$COMPOSE_FILE" run --rm -e PYTHONPATH=/app backend alembic current 2>/dev/null || true
|