#!/bin/bash # ParentFlow Production Deployment Pipeline # This script deploys the complete ParentFlow application suite to production # Run on production server 10.0.0.240 as root set -e # Configuration REPO_URL="https://andrei:33edc%40%40NHY%5E%5E@git.noru1.ro/andrei/maternal-app.git" DEPLOY_DIR="/root/parentflow-production" DB_HOST="10.0.0.207" DB_PORT="5432" DB_USER="postgres" DB_PASSWORD="a3ppq" DB_NAME="parentflow" DB_NAME_ADMIN="parentflowadmin" # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color # Logging function log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" >&2 exit 1 } success() { echo -e "${GREEN}✓${NC} $1" } warning() { echo -e "${YELLOW}⚠${NC} $1" } # Header echo "" echo "============================================" echo " ParentFlow Production Deployment v2.0 " echo "============================================" echo "" # Step 1: Install Node.js 22 log "${CYAN}Step 1: Installing Node.js 22...${NC}" if ! command -v node &> /dev/null || [[ $(node -v | cut -d'v' -f2 | cut -d'.' -f1) -lt 22 ]]; then curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs success "Node.js $(node -v) installed" else success "Node.js $(node -v) already installed" fi # Step 2: Install PM2 globally log "${CYAN}Step 2: Installing PM2...${NC}" if ! command -v pm2 &> /dev/null; then npm install -g pm2@latest success "PM2 installed" else pm2 update success "PM2 updated" fi # Step 3: Install Docker and Docker Compose log "${CYAN}Step 3: Checking Docker installation...${NC}" if ! command -v docker &> /dev/null; then curl -fsSL https://get.docker.com | sh success "Docker installed" else success "Docker already installed" fi if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose success "Docker Compose installed" else success "Docker Compose already installed" fi # Step 4: Install PostgreSQL client log "${CYAN}Step 4: Installing PostgreSQL client...${NC}" if ! command -v psql &> /dev/null; then apt-get update apt-get install -y postgresql-client success "PostgreSQL client installed" else success "PostgreSQL client already installed" fi # Step 5: Clone or update repository log "${CYAN}Step 5: Fetching latest code from main branch...${NC}" if [ -d "$DEPLOY_DIR" ]; then warning "Deployment directory exists, pulling latest changes..." cd "$DEPLOY_DIR" git fetch origin main git reset --hard origin/main git clean -fd else log "Cloning repository..." git clone -b main "$REPO_URL" "$DEPLOY_DIR" cd "$DEPLOY_DIR" fi success "Repository updated to latest main branch" # Step 6: Stop existing services log "${CYAN}Step 6: Stopping existing services...${NC}" if [ -f "./stop-production.sh" ]; then ./stop-production.sh || warning "No services were running" else warning "Stop script not found, continuing..." fi # Step 7: Install dependencies log "${CYAN}Step 7: Installing application dependencies...${NC}" # Backend log "Installing backend dependencies..." cd "$DEPLOY_DIR/maternal-app/maternal-app-backend" rm -rf node_modules package-lock.json npm install --production=false npm update success "Backend dependencies installed" # Frontend log "Installing frontend dependencies..." cd "$DEPLOY_DIR/maternal-web" rm -rf node_modules package-lock.json .next npm install --production=false npm update success "Frontend dependencies installed" # Admin Dashboard log "Installing admin dashboard dependencies..." cd "$DEPLOY_DIR/parentflow-admin" rm -rf node_modules package-lock.json .next npm install --production=false npm update success "Admin dashboard dependencies installed" # Step 8: Set up environment files log "${CYAN}Step 8: Configuring environment...${NC}" cd "$DEPLOY_DIR" # Backend .env cat > "$DEPLOY_DIR/maternal-app/maternal-app-backend/.env.production" << EOF # Production Environment Configuration NODE_ENV=production API_PORT=3020 API_URL=https://api.parentflowapp.com # Database Configuration DATABASE_HOST=${DB_HOST} DATABASE_PORT=${DB_PORT} DATABASE_NAME=${DB_NAME} DATABASE_USER=${DB_USER} DATABASE_PASSWORD=${DB_PASSWORD} DATABASE_SSL=true # Redis Configuration REDIS_HOST=localhost REDIS_PORT=6379 REDIS_URL=redis://localhost:6379 # MongoDB Configuration MONGODB_URI=mongodb://localhost:27017/parentflow_production # MinIO Configuration MINIO_ENDPOINT=localhost MINIO_PORT=9000 MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=parentflow_minio_prod_2024 MINIO_BUCKET=parentflow-files MINIO_USE_SSL=false # JWT Configuration JWT_SECRET=parentflow_jwt_secret_production_2024_secure JWT_EXPIRATION=1h JWT_REFRESH_SECRET=parentflow_refresh_secret_production_2024_secure JWT_REFRESH_EXPIRATION=7d # AI Services (copy from development .env) AI_PROVIDER=azure AZURE_OPENAI_ENABLED=true AZURE_OPENAI_CHAT_ENDPOINT=https://footprints-open-ai.openai.azure.com AZURE_OPENAI_CHAT_DEPLOYMENT=gpt-5-mini AZURE_OPENAI_CHAT_API_VERSION=2025-04-01-preview AZURE_OPENAI_CHAT_API_KEY=a5f7e3e70a454a399f9216853b45e18b AZURE_OPENAI_CHAT_MAX_TOKENS=1000 AZURE_OPENAI_REASONING_EFFORT=medium AZURE_OPENAI_WHISPER_ENDPOINT=https://footprints-ai.openai.azure.com AZURE_OPENAI_WHISPER_DEPLOYMENT=whisper AZURE_OPENAI_WHISPER_API_VERSION=2024-06-01 AZURE_OPENAI_WHISPER_API_KEY=42702a67a41547919877a2ab8e4837f9 AZURE_OPENAI_EMBEDDINGS_ENDPOINT=https://footprints-ai.openai.azure.com AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT=Text-Embedding-ada-002-V2 AZURE_OPENAI_EMBEDDINGS_API_VERSION=2023-05-15 AZURE_OPENAI_EMBEDDINGS_API_KEY=42702a67a41547919877a2ab8e4837f9 # CORS Configuration CORS_ORIGIN=https://web.parentflowapp.com,https://admin.parentflowapp.com # Rate Limiting RATE_LIMIT_TTL=60 RATE_LIMIT_MAX=100 # Email Service MAILGUN_API_KEY= MAILGUN_DOMAIN= EMAIL_FROM=noreply@parentflowapp.com EMAIL_FROM_NAME=ParentFlow # Error Tracking SENTRY_ENABLED=false SENTRY_DSN= EOF # Frontend .env.production cat > "$DEPLOY_DIR/maternal-web/.env.production" << EOF # Frontend Production Configuration NEXT_PUBLIC_API_URL=https://api.parentflowapp.com/api/v1 NEXT_PUBLIC_GRAPHQL_URL=https://api.parentflowapp.com/graphql NEXT_PUBLIC_WS_URL=wss://api.parentflowapp.com NEXT_PUBLIC_APP_URL=https://web.parentflowapp.com NEXT_PUBLIC_APP_NAME=ParentFlow NEXT_PUBLIC_ENABLE_PWA=true NEXT_PUBLIC_ENABLE_ANALYTICS=true EOF # Admin Dashboard .env.production cat > "$DEPLOY_DIR/parentflow-admin/.env.production" << EOF # Admin Dashboard Production Configuration NEXT_PUBLIC_API_URL=https://api.parentflowapp.com/api/v1 NEXT_PUBLIC_APP_URL=https://adminpf.parentflowapp.com NEXT_PUBLIC_APP_NAME=ParentFlow Admin EOF success "Environment files configured" # Step 9: Run database migrations log "${CYAN}Step 9: Running database migrations...${NC}" cd "$DEPLOY_DIR" ./migrate-production.sh || error "Database migration failed" success "Database migrations completed" # Step 10: Build applications log "${CYAN}Step 10: Building applications for production...${NC}" # Build backend log "Building backend..." cd "$DEPLOY_DIR/maternal-app/maternal-app-backend" NODE_ENV=production npm run build success "Backend built" # Build frontend log "Building frontend..." cd "$DEPLOY_DIR/maternal-web" NODE_ENV=production npm run build success "Frontend built" # Build admin dashboard log "Building admin dashboard..." cd "$DEPLOY_DIR/parentflow-admin" NODE_ENV=production npm run build success "Admin dashboard built" # Step 11: Start Docker services log "${CYAN}Step 11: Starting Docker services...${NC}" cd "$DEPLOY_DIR" if docker compose version &> /dev/null; then docker compose -f docker-compose.production.yml up -d else docker-compose -f docker-compose.production.yml up -d fi success "Docker services started" # Step 12: Start application services log "${CYAN}Step 12: Starting application services...${NC}" cd "$DEPLOY_DIR" ./start-production.sh || error "Failed to start services" success "Application services started" # Step 13: Verify deployment log "${CYAN}Step 13: Verifying deployment...${NC}" sleep 10 verify_service() { local service=$1 local port=$2 if lsof -i:$port > /dev/null 2>&1; then success "$service is running on port $port" else error "$service is not running on port $port" fi } verify_service "Backend API" 3020 verify_service "Frontend" 3030 verify_service "Admin Dashboard" 3335 # Final summary echo "" echo "============================================" echo -e "${GREEN} Deployment Completed Successfully! ${NC}" echo "============================================" echo "" echo "Services running at:" echo " Backend API: http://10.0.0.240:3020" echo " Frontend: http://10.0.0.240:3030" echo " Admin Dashboard: http://10.0.0.240:3335" echo "" echo "Configure your nginx proxy to route:" echo " api.parentflowapp.com -> 10.0.0.240:3020" echo " web.parentflowapp.com -> 10.0.0.240:3030" echo " adminpf.parentflowapp.com -> 10.0.0.240:3335" echo "" echo "Management commands:" echo " Start services: ./start-production.sh" echo " Stop services: ./stop-production.sh" echo " View logs: pm2 logs" echo " Monitor: pm2 monit" echo "" log "Deployment completed at $(date)"