#!/bin/bash # Script para iniciar el stack completo en modo producción # Math2 Platform - Production-Grade Deployment set -e # Exit on error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration COMPOSE_FILE="docker-compose.prod.yml" BACKEND_DIR="backend" HEALTH_TIMEOUT=60 echo -e "${BLUE}🚀 Iniciando Math2 Platform en modo producción...${NC}" echo "================================================" # 1. Verificar que existe el archivo docker-compose.prod.yml if [ ! -f "$COMPOSE_FILE" ]; then echo -e "${RED}❌ No se encuentra $COMPOSE_FILE${NC}" exit 1 fi # 2. Verificar variables de entorno críticas echo -e "${BLUE}🔍 Verificando variables de entorno...${NC}" REQUIRED_VARS=( "DATABASE_URL" "DB_PASSWORD" "REDIS_PASSWORD" "JWT_SECRET" ) MISSING_VARS=() for var in "${REQUIRED_VARS[@]}"; do if [ -z "${!var}" ]; then MISSING_VARS+=($var) fi done if [ ${#MISSING_VARS[@]} -ne 0 ]; then echo -e "${RED}❌ Variables de entorno faltantes:${NC}" for var in "${MISSING_VARS[@]}"; do echo " - $var" done echo "" echo -e "${YELLOW}ℹ️ Copia .env.example a .env y configura los valores${NC}" exit 1 fi echo -e "${GREEN}✅ Variables de entorno verificadas${NC}" # 3. Verificar que TypeScript compila echo -e "${BLUE}🔍 Verificando compilación TypeScript...${NC}" cd $BACKEND_DIR if ! npm run type-check > /tmp/type-check.log 2>&1; then echo -e "${RED}❌ TypeScript tiene errores:${NC}" cat /tmp/type-check.log echo "" echo -e "${YELLOW}⚠️ Corrige los errores antes de continuar${NC}" exit 1 fi echo -e "${GREEN}✅ TypeScript compila correctamente${NC}" # 4. Generar Prisma Client echo -e "${BLUE}📦 Generando Prisma Client...${NC}" npx prisma generate --generator client > /tmp/prisma-generate.log 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}❌ Error generando Prisma Client${NC}" cat /tmp/prisma-generate.log exit 1 fi echo -e "${GREEN}✅ Prisma Client generado${NC}" # 5. Construir imágenes Docker echo -e "${BLUE}🐳 Construyendo imágenes Docker...${NC}" cd .. export VERSION=${VERSION:-1.0.0} docker-compose -f $COMPOSE_FILE build --parallel > /tmp/docker-build.log 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}❌ Error construyendo imágenes Docker${NC}" tail -50 /tmp/docker-build.log exit 1 fi echo -e "${GREEN}✅ Imágenes Docker construidas (versión: $VERSION)${NC}" # 6. Verificar volúmenes echo -e "${BLUE}💾 Verificando volúmenes...${NC}" docker volume ls | grep -q "postgres_data\|redis_data" || echo -e "${YELLOW}⚠️ Creando volúmenes por primera vez${NC}" # 7. Iniciar servicios (con DB primero) echo -e "${BLUE}🚀 Iniciando servicios (PostgreSQL y Redis primero)...${NC}" docker-compose -f $COMPOSE_FILE up -d postgres redis # Esperar a que DB esté lista echo -e "${BLUE}⏳ Esperando a que PostgreSQL esté listo...${NC}" for i in $(seq 1 30); do if docker-compose -f $COMPOSE_FILE exec -T postgres pg_isready -U ${DB_USER:-mathuser} -d ${DB_NAME:-mathdb} > /dev/null 2>&1; then echo -e "${GREEN}✅ PostgreSQL listo${NC}" break fi if [ $i -eq 30 ]; then echo -e "${RED}❌ Timeout esperando PostgreSQL${NC}" exit 1 fi sleep 2 done # 8. Aplicar migraciones echo -e "${BLUE}🔄 Aplicando migraciones de base de datos...${NC}" cd $BACKEND_DIR export DATABASE_URL="postgresql://${DB_USER:-mathuser}:${DB_PASSWORD}@localhost:5432/${DB_NAME:-mathdb}" npx prisma migrate deploy > /tmp/migrate.log 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}❌ Error aplicando migraciones${NC}" cat /tmp/migrate.log exit 1 fi echo -e "${GREEN}✅ Migraciones aplicadas${NC}" # 9. Seed si es necesario (solo si la tabla User está vacía) echo -e "${BLUE}🌱 Verificando si se necesita seed...${NC}" SEED_COUNT=$(npx prisma db execute --stdin </dev/null | head -1 SELECT COUNT(*) FROM "User"; EOF ) if [ "$SEED_COUNT" = "0" ] || [ -z "$SEED_COUNT" ]; then echo -e "${BLUE}🌱 Ejecutando seed de base de datos...${NC}" npx prisma db seed > /tmp/seed.log 2>&1 if [ $? -ne 0 ]; then echo -e "${YELLOW}⚠️ Seed no completado (puede ser normal en primer despliegue)${NC}" else echo -e "${GREEN}✅ Seed completado${NC}" fi else echo -e "${GREEN}✅ Datos existentes encontrados, omitiendo seed${NC}" fi cd .. # 10. Iniciar todos los servicios echo -e "${BLUE}🚀 Iniciando todos los servicios...${NC}" docker-compose -f $COMPOSE_FILE up -d # 11. Health checks echo -e "${BLUE}⏳ Esperando servicios...${NC}" sleep 10 echo -e "${BLUE}🏥 Ejecutando health checks...${NC}" # Backend health check echo -n " Backend: " for i in $(seq 1 $HEALTH_TIMEOUT); do if curl -sf http://localhost:3001/health > /dev/null 2>&1; then echo -e "${GREEN}✅ OK${NC}" break fi if [ $i -eq $HEALTH_TIMEOUT ]; then echo -e "${RED}❌ FAIL (timeout)${NC}" fi sleep 1 done # Frontend/Nginx health check echo -n " Frontend: " for i in $(seq 1 $HEALTH_TIMEOUT); do if curl -sf http://localhost > /dev/null 2>&1 || curl -sf http://localhost:80 > /dev/null 2>&1; then echo -e "${GREEN}✅ OK${NC}" break fi if [ $i -eq $HEALTH_TIMEOUT ]; then echo -e "${RED}❌ FAIL (timeout)${NC}" fi sleep 1 done # Verificar workers (opcional, no crítico) echo -n " Workers: " WORKER_COUNT=$(docker-compose -f $COMPOSE_FILE ps -q pdf-worker exercise-worker notification-worker 2>/dev/null | wc -l) if [ "$WORKER_COUNT" -ge 3 ]; then echo -e "${GREEN}✅ OK ($WORKER_COUNT workers)${NC}" else echo -e "${YELLOW}⚠️ Parcial ($WORKER_COUNT/3 workers)${NC}" fi # 12. Mostrar resumen echo "" echo -e "${GREEN}================================================${NC}" echo -e "${GREEN}✅ Math2 Platform iniciada en modo producción${NC}" echo -e "${GREEN}================================================${NC}" echo "" echo -e "${BLUE}📊 Accesos:${NC}" echo " • Dashboard: http://localhost" echo " • API: http://localhost:3001" echo " • Health Check: http://localhost:3001/health" echo "" echo -e "${BLUE}🔧 Comandos útiles:${NC}" echo " • Ver logs: docker-compose -f $COMPOSE_FILE logs -f" echo " • Detener: docker-compose -f $COMPOSE_FILE down" echo " • Status: docker-compose -f $COMPOSE_FILE ps" echo " • Verificar: ./scripts/verify-production.sh" echo "" echo -e "${YELLOW}⚠️ IMPORTANTE: Este es un entorno local de producción${NC}" echo -e "${YELLOW} Para deployment real, configura SSL y dominio${NC}" echo ""