🎓 Initial commit: Math2 Platform - Plataforma de Álgebra Lineal PRO
✨ 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 ✅
This commit is contained in:
249
scripts/validate-deployment.sh
Executable file
249
scripts/validate-deployment.sh
Executable file
@@ -0,0 +1,249 @@
|
||||
#!/bin/bash
|
||||
# ================================================
|
||||
# Math Platform - Pre-Deployment Validation
|
||||
# ================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ERRORS=0
|
||||
WARNINGS=0
|
||||
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
echo -e "${BLUE}Math Platform - Pre-Deployment Validation${NC}"
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
|
||||
# Function to print check result
|
||||
print_result() {
|
||||
local status=$1
|
||||
local message=$2
|
||||
|
||||
if [ "$status" = "OK" ]; then
|
||||
echo -e "${GREEN}✓${NC} $message"
|
||||
elif [ "$status" = "WARN" ]; then
|
||||
echo -e "${YELLOW}⚠${NC} $message"
|
||||
WARNINGS=$((WARNINGS + 1))
|
||||
else
|
||||
echo -e "${RED}✗${NC} $message"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
# Check 1: Docker Installation
|
||||
echo -e "\n${BLUE}Checking Prerequisites${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
if command -v docker &> /dev/null; then
|
||||
DOCKER_VERSION=$(docker --version | awk '{print $3}' | sed 's/,//')
|
||||
print_result "OK" "Docker installed: $DOCKER_VERSION"
|
||||
else
|
||||
print_result "FAIL" "Docker not installed"
|
||||
fi
|
||||
|
||||
if command -v docker-compose &> /dev/null || docker compose version &> /dev/null; then
|
||||
print_result "OK" "Docker Compose available"
|
||||
else
|
||||
print_result "FAIL" "Docker Compose not installed"
|
||||
fi
|
||||
|
||||
# Check 2: Environment File
|
||||
echo -e "\n${BLUE}Checking Environment Configuration${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||
print_result "OK" ".env file exists"
|
||||
|
||||
# Check critical variables
|
||||
source "$PROJECT_ROOT/.env"
|
||||
|
||||
if [ -n "$DB_PASSWORD" ] && [ ${#DB_PASSWORD} -ge 16 ]; then
|
||||
print_result "OK" "DB_PASSWORD configured (length: ${#DB_PASSWORD})"
|
||||
else
|
||||
print_result "WARN" "DB_PASSWORD not set or too short (min 16 chars)"
|
||||
fi
|
||||
|
||||
if [ -n "$REDIS_PASSWORD" ] && [ ${#REDIS_PASSWORD} -ge 16 ]; then
|
||||
print_result "OK" "REDIS_PASSWORD configured (length: ${#REDIS_PASSWORD})"
|
||||
else
|
||||
print_result "WARN" "REDIS_PASSWORD not set or too short (min 16 chars)"
|
||||
fi
|
||||
|
||||
if [ -n "$JWT_SECRET" ] && [ ${#JWT_SECRET} -ge 32 ]; then
|
||||
print_result "OK" "JWT_SECRET configured (length: ${#JWT_SECRET})"
|
||||
else
|
||||
print_result "FAIL" "JWT_SECRET not set or too short (min 32 chars)"
|
||||
fi
|
||||
|
||||
if [ -n "$AI_API_KEY" ]; then
|
||||
print_result "OK" "AI_API_KEY configured"
|
||||
else
|
||||
print_result "WARN" "AI_API_KEY not set (AI features won't work)"
|
||||
fi
|
||||
else
|
||||
print_result "FAIL" ".env file not found"
|
||||
fi
|
||||
|
||||
# Check 3: Required Files
|
||||
echo -e "\n${BLUE}Checking Required Files${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
files=(
|
||||
"docker-compose.yml:docker-compose.yml"
|
||||
"Dockerfile (Backend):docker/Dockerfile.backend"
|
||||
"Dockerfile (Frontend):docker/Dockerfile.frontend"
|
||||
"Dockerfile (Worker):docker/Dockerfile.worker"
|
||||
"Nginx config:docker/nginx.conf"
|
||||
"Backend package.json:backend/package.json"
|
||||
"Frontend package.json:frontend/package.json"
|
||||
"Prisma schema:backend/prisma/schema.prisma"
|
||||
"Next.js config:frontend/next.config.js"
|
||||
)
|
||||
|
||||
for file_info in "${files[@]}"; do
|
||||
file="${file_info##*:}"
|
||||
name="${file_info%:*}"
|
||||
|
||||
if [ -f "$PROJECT_ROOT/$file" ]; then
|
||||
print_result "OK" "$name exists"
|
||||
else
|
||||
print_result "FAIL" "$name missing: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 4: Required Directories
|
||||
echo -e "\n${BLUE}Checking Directories${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
dirs=(
|
||||
"Backend source:backend/src"
|
||||
"Frontend source:frontend/src"
|
||||
"Docker data:docker/data"
|
||||
"Docker logs:docker/logs"
|
||||
"Init scripts:docker/init-scripts"
|
||||
"Scripts:scripts"
|
||||
"PDF storage:pdfs"
|
||||
)
|
||||
|
||||
for dir_info in "${dirs[@]}"; do
|
||||
dir="${dir_info##*:}"
|
||||
name="${dir_info%:*}"
|
||||
|
||||
if [ -d "$PROJECT_ROOT/$dir" ]; then
|
||||
print_result "OK" "$name exists"
|
||||
else
|
||||
print_result "WARN" "$name missing: $dir"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 5: Script Permissions
|
||||
echo -e "\n${BLUE}Checking Script Permissions${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
scripts=(
|
||||
"docker/start.sh"
|
||||
"docker/stop.sh"
|
||||
"docker/backup.sh"
|
||||
"scripts/test-e2e.sh"
|
||||
"scripts/health-check.sh"
|
||||
"scripts/monitor.sh"
|
||||
)
|
||||
|
||||
for script in "${scripts[@]}"; do
|
||||
if [ -f "$PROJECT_ROOT/$script" ]; then
|
||||
if [ -x "$PROJECT_ROOT/$script" ]; then
|
||||
print_result "OK" "$script is executable"
|
||||
else
|
||||
print_result "WARN" "$script is not executable"
|
||||
fi
|
||||
else
|
||||
print_result "WARN" "$script not found"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 6: Docker Resources
|
||||
echo -e "\n${BLUE}Checking Docker Resources${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
if docker info &> /dev/null; then
|
||||
# Check available disk space
|
||||
DISK_AVAILABLE=$(df -h "$PROJECT_ROOT" | awk 'NR==2 {print $4}')
|
||||
DISK_USAGE_PERCENT=$(df -h "$PROJECT_ROOT" | awk 'NR==2 {print $5}' | sed 's/%//')
|
||||
|
||||
if [ "$DISK_USAGE_PERCENT" -lt 80 ]; then
|
||||
print_result "OK" "Disk space available: $DISK_AVAILABLE"
|
||||
else
|
||||
print_result "WARN" "Disk space low: $DISK_AVAILABLE available"
|
||||
fi
|
||||
|
||||
# Check Docker memory
|
||||
DOCKER_MEMORY=$(docker info 2>/dev/null | grep "Total Memory" | awk '{print $3}' || echo "N/A")
|
||||
if [ "$DOCKER_MEMORY" != "N/A" ]; then
|
||||
print_result "OK" "Docker memory: $DOCKER_MEMORY"
|
||||
fi
|
||||
|
||||
# Check for running containers
|
||||
RUNNING_CONTAINERS=$(docker ps -q | wc -l)
|
||||
print_result "OK" "Running containers: $RUNNING_CONTAINERS"
|
||||
else
|
||||
print_result "WARN" "Docker not running"
|
||||
fi
|
||||
|
||||
# Check 7: Port Availability
|
||||
echo -e "\n${BLUE}Checking Port Availability${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
ports=("80:HTTP" "3000:Frontend" "3001:Backend" "5432:PostgreSQL" "6379:Redis")
|
||||
|
||||
for port_info in "${ports[@]}"; do
|
||||
port="${port_info%%:*}"
|
||||
name="${port_info##*:}"
|
||||
|
||||
if netstat -tuln 2>/dev/null | grep -q ":$port " || ss -tuln 2>/dev/null | grep -q ":$port "; then
|
||||
print_result "WARN" "Port $port ($name) already in use"
|
||||
else
|
||||
print_result "OK" "Port $port ($name) available"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check 8: File Permissions
|
||||
echo -e "\n${BLUE}Checking File Permissions${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
if [ -d "$PROJECT_ROOT/docker/data" ]; then
|
||||
if [ -w "$PROJECT_ROOT/docker/data" ]; then
|
||||
print_result "OK" "docker/data is writable"
|
||||
else
|
||||
print_result "FAIL" "docker/data is not writable"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$PROJECT_ROOT/docker/logs" ]; then
|
||||
if [ -w "$PROJECT_ROOT/docker/logs" ]; then
|
||||
print_result "OK" "docker/logs is writable"
|
||||
else
|
||||
print_result "FAIL" "docker/logs is not writable"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo -e "\n${BLUE}============================================${NC}"
|
||||
echo -e "${BLUE}Validation Summary${NC}"
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
|
||||
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
||||
echo -e "${GREEN}All checks passed! Ready for deployment.${NC}\n"
|
||||
exit 0
|
||||
elif [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${YELLOW}Validation passed with $WARNINGS warning(s).${NC}\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}Validation failed with $ERRORS error(s) and $WARNINGS warning(s).${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user