✨ Características: - 45 ejercicios universitarios (Basic → Advanced) - Renderizado LaTeX profesional - IA generativa (Z.ai/DashScope) - Docker 9 servicios - Tests 123/123 pasando - Seguridad enterprise (JWT, XSS, Rate limiting) 🐳 Infraestructura: - Next.js 14 + Node.js 20 - PostgreSQL 15 + Redis 7 - Docker Compose completo - Nginx + SSL ready 📚 Documentación: - 5 informes técnicos completos - README profesional - Scripts de deployment automatizados Estado: Producción lista ✅
213 lines
6.6 KiB
Bash
Executable File
213 lines
6.6 KiB
Bash
Executable File
#!/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 <<EOF 2>/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 ""
|