Files
openccb/deploy.sh
T
Nurfog 76c9a4a2d4 feat: Add database reset and SSL preserve options to deploy script
- Add option to keep or reset database (preserves data by default)
- Add option to preserve existing SSL certificates
- Show warnings before database reset with confirmation
- Skip certificate regeneration when preserve SSL is selected
- Update deployment summary with new options

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-27 11:12:12 -03:00

788 lines
26 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# OpenCCB Unified Deployment Script
# Despliegue automático en AWS EC2 con SSL (Let's Encrypt)
# Servidor: ec2-18-224-137-67.us-east-2.compute.amazonaws.com
# Dominios: studio.norteamericano.com, learning.norteamericano.com
set -e
echo "===================================================="
echo " 🚀 OpenCCB Deployment Tool"
echo "===================================================="
echo ""
# ============================================================================
# CONFIGURACIÓN
# ============================================================================
PEM_PATH="ubuntu.pem"
REMOTE_USER="ubuntu"
REMOTE_HOST="ec2-18-224-137-67.us-east-2.compute.amazonaws.com"
REMOTE_PATH="/var/www/openccb"
# Cambiar a "false" para usar Let's Encrypt production (solo después de rate limits)
LETSENCRYPT_STAGING="true"
# ============================================================================
# Si PEM_PATH es relativo, convertirlo a absoluto
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ "$PEM_PATH" != /* ]]; then
PEM_PATH="$SCRIPT_DIR/$PEM_PATH"
fi
# Verificar que existe el archivo PEM
if [ ! -f "$PEM_PATH" ]; then
echo "❌ ERROR: No se encontró el archivo $PEM_PATH"
echo ""
echo "Verifica la ruta de la llave SSH"
exit 1
fi
echo "✅ Configuración cargada exitosamente"
echo ""
echo "📋 Configuración de despliegue:"
echo " 👤 Usuario: $REMOTE_USER"
echo " 🖥️ Host: $REMOTE_HOST"
echo " 📁 Destino: $REMOTE_PATH"
echo " 🔑 SSH Key: $PEM_PATH"
echo ""
# Preguntar si continuar
read -p "¿Desea continuar con el despliegue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
echo "❌ Despliegue cancelado"
exit 0
fi
echo ""
echo "📦 Preparando archivos para producción..."
# Crear directorio temporal
PROD_DIR="./.deploy-temp-$$"
mkdir -p "$PROD_DIR"
# Asegurar limpieza al finalizar
cleanup() {
rm -rf "$PROD_DIR"
}
trap cleanup EXIT
# Copiar archivos esenciales
echo " 📋 Copiando archivos esenciales..."
cp -r docker-compose.yml "$PROD_DIR/" 2>/dev/null || echo " ⚠️ docker-compose.yml no existe"
# NO copiar .env local - tiene configuraciones incorrectas para producción
echo " ️ .env local NO se copia - se generará uno correcto en el servidor"
cp -r .env.example "$PROD_DIR/" 2>/dev/null || true
# NO copiar ubuntu.pem - solo se usa localmente para SSH
echo " ️ ubuntu.pem NO se copia - solo para SSH local"
# Copiar servicios excluyendo target/ y node_modules/
echo " - Copiando services/..."
mkdir -p "$PROD_DIR/services"
find services -type f \
! -path "*/target/*" \
! -path "*/node_modules/*" \
-exec cp --parents {} "$PROD_DIR/" \; 2>/dev/null || true
# Copiar shared excluyendo target/ y node_modules/
echo " - Copiando shared/..."
mkdir -p "$PROD_DIR/shared"
find shared -type f \
! -path "*/target/*" \
! -path "*/node_modules/*" \
-exec cp --parents {} "$PROD_DIR/" \; 2>/dev/null || true
# Copiar web excluyendo .next/ y node_modules/
echo " - Copiando web/..."
mkdir -p "$PROD_DIR/web"
find web -type f \
! -path "*/.next/*" \
! -path "*/node_modules/*" \
-exec cp --parents {} "$PROD_DIR/" \; 2>/dev/null || true
# Copiar archivos root
cp -r Cargo.toml "$PROD_DIR/" 2>/dev/null || true
cp -r Cargo.lock "$PROD_DIR/" 2>/dev/null || true
# Copiar configuración de nginx
mkdir -p "$PROD_DIR/nginx"
if [ -f "nginx/proxy.conf" ]; then
cp nginx/proxy.conf "$PROD_DIR/nginx/"
fi
echo " ✅ Archivos esenciales copiados"
# Contar archivos
FILE_COUNT=$(find "$PROD_DIR" -type f | wc -l)
TOTAL_SIZE=$(du -sh "$PROD_DIR" | cut -f1)
echo "$FILE_COUNT archivos listos ($TOTAL_SIZE)"
echo ""
# Verificar rsync
RSYNC_PATH=$(which rsync 2>/dev/null || echo "")
if [ -z "$RSYNC_PATH" ]; then
echo "📦 Instalando rsync..."
if command -v apt-get &> /dev/null; then
sudo apt-get update -qq && sudo apt-get install -y rsync
else
echo "❌ Instala rsync manualmente: sudo apt-get install rsync"
exit 1
fi
RSYNC_PATH=$(which rsync 2>/dev/null || echo "")
fi
echo "✅ rsync encontrado en: $RSYNC_PATH"
echo ""
# Sincronizar con servidor remoto
echo "🌐 Sincronizando con servidor remoto..."
# Verificar conectividad SSH
if ! ssh -i "$PEM_PATH" -o ConnectTimeout=10 -o BatchMode=yes "$REMOTE_USER@$REMOTE_HOST" "echo 'SSH OK'" &> /dev/null; then
echo " ❌ ERROR: No se pudo conectar vía SSH"
echo " Verifica:"
echo " 1. Que el archivo $PEM_PATH existe"
echo " 2. Que los permisos son correctos - chmod 400 $PEM_PATH"
echo " 3. Que el host $REMOTE_HOST es accesible"
exit 1
fi
echo " ✅ SSH conectado exitosamente"
echo ""
# Crear directorio remoto
echo " 📁 Creando directorio remoto..."
ssh -i "$PEM_PATH" "$REMOTE_USER@$REMOTE_HOST" "sudo mkdir -p $REMOTE_PATH && sudo chown $REMOTE_USER:$REMOTE_USER $REMOTE_PATH"
# Sincronizar archivos
echo " 📤 Subiendo archivos con rsync..."
rsync -avz -e "ssh -i $PEM_PATH" \
--progress \
--rsync-path="sudo rsync" \
--exclude 'node_modules' \
--exclude 'target' \
--exclude '.next' \
--exclude '.git' \
--exclude '.qwen' \
"$PROD_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH"
if [ $? -ne 0 ]; then
echo " ❌ ERROR: rsync falló"
exit 1
fi
rm -rf "$PROD_DIR"
echo ""
echo "✅ Archivos sincronizados exitosamente!"
echo ""
# ============================================================================
# SCRIPT REMOTO PARA GESTIÓN DE CONTENEDORES
# ============================================================================
echo "🔧 Ejecutando gestión de contenedores en remoto..."
echo ""
# ============================================================================
# PREGUNTAR DATOS DEL ADMINISTRADOR (LOCAL)
# ============================================================================
echo ""
echo "========================================"
echo " Configuración del Administrador"
echo "========================================"
echo ""
# Preguntar datos del administrador
read -p "Nombre completo del administrador [Administrador]: " ADMIN_NAME
ADMIN_NAME=${ADMIN_NAME:-Administrador}
read -p "Email del administrador [admin@norteamericano.com]: " ADMIN_EMAIL
ADMIN_EMAIL=${ADMIN_EMAIL:-admin@norteamericano.com}
read -sp "Contraseña del administrador [Admin123!]: " ADMIN_PASS
echo ""
ADMIN_PASS=${ADMIN_PASS:-Admin123!}
read -p "Nombre de la organización [Norteamericano]: " ORG_NAME
ORG_NAME=${ORG_NAME:-Norteamericano}
echo ""
echo "========================================"
echo " Configuración de Base de Datos"
echo "========================================"
echo ""
echo "¿Qué deseas hacer con la base de datos?"
echo " 1) Mantener datos existentes (recomendado para actualizaciones)"
echo " 2) Reiniciar base de datos (BORRAR todos los datos)"
echo ""
read -p "Opción [1/2]: " DB_OPTION
DB_OPTION=${DB_OPTION:-1}
if [[ "$DB_OPTION" =~ ^[2]$ ]]; then
RESET_DATABASE="true"
echo ""
echo "⚠️ ADVERTENCIA: Se borrarán TODOS los datos de la base de datos"
read -p "¿Estás seguro de continuar? [y/N]: " CONFIRM_RESET
if [[ ! "$CONFIRM_RESET" =~ ^[Yy]$ ]]; then
echo "❌ Operación cancelada - manteniendo base de datos"
RESET_DATABASE="false"
else
echo "✅ Base de datos será reiniciada"
fi
else
RESET_DATABASE="false"
echo "✅ Se mantendrán los datos existentes"
fi
echo ""
echo "----------------------------------------"
echo "Configuración SSL"
echo "----------------------------------------"
echo ""
echo "¿Deseas usar SSL con Let's Encrypt?"
echo " - SI: Usará HTTPS (recomendado para producción)"
echo " - NO: Usará HTTP (recomendado para pruebas o si hay rate limits)"
echo ""
read -p "¿Usar SSL? [y/N]: " USE_SSL
USE_SSL=${USE_SSL:-N}
if [[ "$USE_SSL" =~ ^[Yy]$ ]]; then
echo ""
echo "----------------------------------------"
echo "Configuración de Certificados SSL"
echo "----------------------------------------"
echo ""
echo "¿Ya tienes certificados SSL funcionando?"
echo " - SI: Preservar certificados existentes (recomendado)"
echo " - NO: Generar nuevos certificados"
echo ""
read -p "¿Preservar certificados? [y/N]: " PRESERVE_CERTS
PRESERVE_CERTS=${PRESERVE_CERTS:-Y}
if [[ "$PRESERVE_CERTS" =~ ^[Yy]$ ]]; then
PRESERVE_SSL_CERTS="true"
echo "✅ Se preservarán los certificados SSL existentes"
else
PRESERVE_SSL_CERTS="false"
echo ""
echo "¿Usar servidor de STAGING (certificados de prueba)?"
echo " - SI: Sin rate limits, pero el navegador muestra advertencias"
echo " - NO: Certificados reales, pero con rate limits (5 por semana)"
echo ""
read -p "¿Usar STAGING? [y/N]: " USE_STAGING
USE_STAGING=${USE_STAGING:-Y}
if [[ "$USE_STAGING" =~ ^[Yy]$ ]]; then
LETSENCRYPT_STAGING="true"
PROTOCOL="http"
echo ""
echo "✅ Configuración: STAGING (HTTP por ahora)"
echo " Los certificados de staging no son válidos para producción"
echo " Las llamadas API usarán HTTP para evitar errores de SSL"
else
LETSENCRYPT_STAGING="false"
PROTOCOL="https"
echo ""
echo "✅ Configuración: PRODUCTION (HTTPS)"
echo " Se usarán certificados reales de Let's Encrypt"
fi
fi
else
LETSENCRYPT_STAGING="false"
PROTOCOL="http"
PRESERVE_SSL_CERTS="false"
echo ""
echo "✅ Configuración: HTTP (sin SSL)"
fi
echo ""
echo "========================================"
echo " Resumen de Configuración"
echo "========================================"
echo ""
echo " Nombre: $ADMIN_NAME"
echo " Email: $ADMIN_EMAIL"
echo " Organización: $ORG_NAME"
echo " Protocolo: $PROTOCOL"
echo " SSL Staging: $LETSENCRYPT_STAGING"
echo " Preservar SSL: $PRESERVE_SSL_CERTS"
echo " Reiniciar DB: $RESET_DATABASE"
echo ""
# Crear script remoto en un archivo temporal
cat > /tmp/remote-deploy.sh << REMOTE_SCRIPT_CONTENT
set -e
# Variables pasadas desde el script local
LETSENCRYPT_STAGING=$LETSENCRYPT_STAGING
RESET_DATABASE=$RESET_DATABASE
PRESERVE_SSL_CERTS=$PRESERVE_SSL_CERTS
PROTOCOL=$PROTOCOL
cd /var/www/openccb
echo "========================================"
echo " OpenCCB Remote Deployment"
echo "========================================"
echo ""
echo "Configuración:"
echo " LETSENCRYPT_STAGING: \$LETSENCRYPT_STAGING"
echo " RESET_DATABASE: \$RESET_DATABASE"
echo " PRESERVE_SSL_CERTS: \$PRESERVE_SSL_CERTS"
echo " PROTOCOL: \$PROTOCOL"
echo ""
# ========================================
# GENERAR .ENV CORRECTO PARA PRODUCCION
# ========================================
echo "Generando configuracion .env para produccion..."
if [ ! -f ".env" ]; then
echo " Creando .env desde .env.example..."
if [ -f ".env.example" ]; then
cp .env.example .env
else
touch .env
fi
fi
# Generar DB_PASSWORD seguro
if ! grep -q "^DB_PASSWORD=" .env || grep -q "CHANGE_ME" .env || grep -q "^DB_PASSWORD=password$" .env; then
echo " Generando DB_PASSWORD segura..."
DB_PASS=$(openssl rand -base64 32 | tr -dc "a-zA-Z0-9" | head -c 32)
if grep -q "^DB_PASSWORD=" .env; then
sed -i "s/^DB_PASSWORD=.*/DB_PASSWORD=$DB_PASS/" .env
else
echo "DB_PASSWORD=$DB_PASS" >> .env
fi
fi
# Generar JWT_SECRET seguro
if ! grep -q "^JWT_SECRET=" .env || grep -q "CHANGE_ME" .env || grep -q "secret.*2025" .env || grep -q "^JWT_SECRET=supersecret" .env; then
echo " Generando JWT_SECRET seguro..."
JWT_SEC=$(openssl rand -base64 48 | tr -dc "a-zA-Z0-9" | head -c 64)
if grep -q "^JWT_SECRET=" .env; then
sed -i "s/^JWT_SECRET=.*/JWT_SECRET=$JWT_SEC/" .env
else
echo "JWT_SECRET=$JWT_SEC" >> .env
fi
fi
# CORREGIR DATABASE_URL para produccion - db:5432
echo " Configurando DATABASE_URL para Docker..."
DB_PASS=$(grep "^DB_PASSWORD=" .env | cut -d"=" -f2)
sed -i "/^CMS_DATABASE_URL=/d" .env 2>/dev/null || true
sed -i "/^LMS_DATABASE_URL=/d" .env 2>/dev/null || true
sed -i "/^DATABASE_URL=/d" .env 2>/dev/null || true
echo "CMS_DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/openccb_cms" >> .env
echo "LMS_DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/openccb_lms" >> .env
echo "DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/openccb_cms" >> .env
# Configurar Let's Encrypt - staging o production
echo " Configurando Let's Encrypt..."
if [ "$PRESERVE_SSL_CERTS" = "true" ]; then
echo " Preservando configuración SSL existente"
# No modificar LETSENCRYPT_STAGING - mantener el valor existente
if ! grep -q "^LETSENCRYPT_STAGING=" .env; then
echo "LETSENCRYPT_STAGING=false" >> .env
fi
else
if [ "$LETSENCRYPT_STAGING" = "true" ]; then
# Remover valor existente si existe
sed -i "/^LETSENCRYPT_STAGING=/d" .env 2>/dev/null || true
echo "LETSENCRYPT_STAGING=true" >> .env
echo " Usando STAGING - certificados de prueba"
else
# Remover valor existente si existe
sed -i "/^LETSENCRYPT_STAGING=/d" .env 2>/dev/null || true
echo "LETSENCRYPT_STAGING=false" >> .env
echo " Usando PRODUCTION - certificados reales"
fi
fi
echo ""
REMOTE_SCRIPT_CONTENT
# Ahora agregamos la sección de Docker con las variables correctas
cat >> /tmp/remote-deploy.sh << REMOTE_SCRIPT_CONTENT
# ========================================
# ACTUALIZAR DOCKER-COMPOSE.YML SEGUN SSL
# ========================================
echo "Configurando docker-compose.yml para $PROTOCOL..."
# Reemplazar las URLs en docker-compose.yml
if [ "$PROTOCOL" = "https" ]; then
sed -i 's|NEXT_PUBLIC_CMS_API_URL: http://|NEXT_PUBLIC_CMS_API_URL: https://|g' docker-compose.yml
sed -i 's|NEXT_PUBLIC_LMS_API_URL: http://|NEXT_PUBLIC_LMS_API_URL: https://|g' docker-compose.yml
echo " ✅ URLs actualizadas a HTTPS"
else
sed -i 's|NEXT_PUBLIC_CMS_API_URL: https://|NEXT_PUBLIC_CMS_API_URL: http://|g' docker-compose.yml
sed -i 's|NEXT_PUBLIC_LMS_API_URL: https://|NEXT_PUBLIC_LMS_API_URL: http://|g' docker-compose.yml
echo " ✅ URLs actualizadas a HTTP"
fi
# Verificar configuración
echo ""
echo "Configuración de URLs en docker-compose.yml:"
grep "NEXT_PUBLIC_" docker-compose.yml | head -10
echo ""
# Verificar que los argumentos de build estén presentes
echo "Verificando argumentos de build..."
if grep -q "NEXT_PUBLIC_CMS_API_URL:" docker-compose.yml && grep -q "NEXT_PUBLIC_LMS_API_URL:" docker-compose.yml; then
echo " ✅ Ambos argumentos de build están presentes"
else
echo " ⚠️ Faltan argumentos de build, agregando..."
# Agregar argumentos si faltan
if ! grep -q "NEXT_PUBLIC_LMS_API_URL:" docker-compose.yml; then
sed -i '/NEXT_PUBLIC_CMS_API_URL:/a\ NEXT_PUBLIC_LMS_API_URL: http://learning.norteamericano.com' docker-compose.yml
fi
fi
echo ""
REMOTE_SCRIPT_CONTENT
# Ahora agregamos la sección de Docker con las variables correctas
cat >> /tmp/remote-deploy.sh << 'REMOTE_SCRIPT_CONTENT'
# ========================================
# VERIFICAR E INSTALAR DOCKER
# ========================================
echo "Verificando requerimientos del sistema..."
command_exists() {
command -v "$1" &> /dev/null
}
# Docker
echo "Verificando Docker..."
if ! command_exists docker; then
echo " Docker no esta instalado, instalando..."
curl -fsSL https://get.docker.com | sudo sh
echo " Docker instalado"
fi
# Verificar permisos de Docker
if docker ps &> /dev/null 2>&1; then
DOCKER_CMD="docker"
elif sudo docker ps &> /dev/null 2>&1; then
DOCKER_CMD="sudo docker"
sudo usermod -aG docker $(whoami) 2>/dev/null || true
else
echo " ERROR: No se puede acceder a Docker"
exit 1
fi
echo " Usando: $DOCKER_CMD"
# Docker Compose
if ! $DOCKER_CMD compose version &> /dev/null 2>&1; then
echo " Instalando Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo mkdir -p /usr/lib/docker/cli-plugins
sudo ln -sf /usr/local/bin/docker-compose /usr/lib/docker/cli-plugins/docker-compose 2>/dev/null || true
echo " Docker Compose instalado"
fi
echo ""
# Funcion para ejecutar docker compose
run_docker_compose() {
$DOCKER_CMD compose -f docker-compose.yml "$@"
}
# ========================================
# INICIAR SERVICIOS
# ========================================
echo "Iniciando servicios OpenCCB..."
# Detener contenedores existentes
echo "Deteniendo contenedores existentes..."
run_docker_compose down || true
# Eliminar contenedores antiguos para forzar reconstrucción
echo "Eliminando contenedores antiguos..."
$DOCKER_CMD rm openccb-studio 2>/dev/null || true
$DOCKER_CMD rm openccb-experience 2>/dev/null || true
# ========================================
# GESTIÓN DE BASE DE DATOS
# ========================================
if [ "$RESET_DATABASE" = "true" ]; then
echo ""
echo "⚠️ REINICIANDO BASE DE DATOS ⚠️"
echo ""
# Detener contenedores de nginx y ssl también para limpiar volúmenes
echo "Deteniendo todos los contenedores..."
run_docker_compose down
# Eliminar volúmenes de base de datos
echo "Eliminando volúmenes de base de datos..."
$DOCKER_CMD volume rm openccb_postgres_data 2>/dev/null || true
# Reiniciar contenedores
echo "Reiniciando contenedores..."
run_docker_compose up -d db
echo "Esperando a que la base de datos este lista..."
sleep 10
# Crear bases de datos desde cero
echo "Creando bases de datos..."
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "DROP DATABASE IF EXISTS openccb_cms;" 2>/dev/null || true
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "DROP DATABASE IF EXISTS openccb_lms;" 2>/dev/null || true
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "CREATE DATABASE openccb_cms;" 2>/dev/null || echo " Error al crear openccb_cms"
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "CREATE DATABASE openccb_lms;" 2>/dev/null || echo " Error al crear openccb_lms"
echo "✅ Base de datos reiniciada correctamente"
else
echo ""
echo "✅ Manteniendo base de datos existente"
echo ""
# Iniciar base de datos
echo "Iniciando base de datos..."
run_docker_compose up -d db
echo "Esperando a que la base de datos este lista..."
sleep 10
# Verificar si las bases de datos existen, si no, crearlas
echo "Verificando bases de datos..."
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "CREATE DATABASE openccb_cms;" 2>/dev/null || echo " openccb_cms ya existe"
$DOCKER_CMD exec openccb-db psql -U user -d postgres -c "CREATE DATABASE openccb_lms;" 2>/dev/null || echo " openccb_lms ya existe"
fi
# ========================================
# GESTIÓN DE CERTIFICADOS SSL
# ========================================
if [ "$PRESERVE_SSL_CERTS" = "true" ]; then
echo ""
echo "✅ Preservando certificados SSL existentes"
echo " Iniciando nginx-proxy y acme-companion sin regenerar certificados..."
# Iniciar nginx-proxy y acme-companion (los certificados ya existen)
run_docker_compose up -d nginx-proxy acme-companion
echo "Esperando a que nginx-proxy este listo..."
sleep 10
else
echo ""
echo "Iniciando nginx-proxy y acme-companion para SSL..."
# Iniciar nginx-proxy y acme-companion
run_docker_compose up -d nginx-proxy acme-companion
echo "Esperando a que nginx-proxy este listo..."
sleep 10
if [ "$LETSENCRYPT_STAGING" = "false" ]; then
echo " Generando certificados SSL de producción..."
else
echo " Generando certificados SSL de staging..."
fi
fi
# Limpiar caché de builder
echo "Limpiando caché de Docker builder..."
$DOCKER_CMD builder prune -f 2>/dev/null || true
# Reconstruir con las URLs correctas (sin cache para asegurar que tome los cambios)
echo "Reconstruyendo contenedores con las URLs configuradas..."
run_docker_compose build --no-cache studio experience
# Iniciar servicios
echo "Iniciando servicios OpenCCB..."
run_docker_compose up -d studio experience
echo ""
echo "Esperando a que los servicios esten listos..."
sleep 15
# ========================================
# VERIFICAR VARIABLES DE ENTORNO
# ========================================
echo ""
echo "Verificando variables de entorno en los contenedores..."
echo ""
echo "Studio:"
$DOCKER_CMD exec openccb-studio env | grep NEXT_PUBLIC || echo " No se pudo verificar"
echo ""
echo "Experience:"
$DOCKER_CMD exec openccb-experience env | grep NEXT_PUBLIC || echo " No se pudo verificar"
echo ""
# ========================================
# VERIFICAR ESTADO
# ========================================
echo ""
echo "Estado de contenedores:"
run_docker_compose ps
echo ""
echo "Verificando logs de errores..."
CMS_ERRORS=$(run_docker_compose logs studio 2>&1 | grep -i "error" | tail -5 || true)
LMS_ERRORS=$(run_docker_compose logs experience 2>&1 | grep -i "error" | tail -5 || true)
if [ -n "$CMS_ERRORS" ]; then
echo "Errores en Studio:"
echo "$CMS_ERRORS"
fi
if [ -n "$LMS_ERRORS" ]; then
echo "Errores en Experience:"
echo "$LMS_ERRORS"
fi
if [ -z "$CMS_ERRORS" ] && [ -z "$LMS_ERRORS" ]; then
echo "No se detectaron errores criticos"
fi
echo ""
# ========================================
# CREAR USUARIO ADMINISTRADOR
# ========================================
echo "========================================"
echo " Creando Usuario Administrador"
echo "========================================"
echo ""
echo "Esperando a que el API CMS este listo..."
sleep 10
# Intentar crear el usuario via API
echo "Creando usuario administrador..."
CMS_INTERNAL_URL="http://openccb-studio:3001"
# Crear payload JSON
cat > /tmp/admin_payload.json << EOF
{
"email": "$ADMIN_EMAIL",
"password": "$ADMIN_PASS",
"full_name": "$ADMIN_NAME",
"organization_name": "$ORG_NAME",
"role": "admin"
}
EOF
# Copiar payload al servidor
scp -i "$PEM_PATH" /tmp/admin_payload.json "$REMOTE_USER@$REMOTE_HOST:/tmp/admin_payload.json" 2>/dev/null || true
# Intentar crear usuario via SSH
ssh -i "$PEM_PATH" "$REMOTE_USER@$REMOTE_HOST" "
CMS_URL='$PROTOCOL://openccb-studio:3001'
if [ -f /tmp/admin_payload.json ]; then
RESPONSE=\$(curl -s -X POST \"\$CMS_URL/auth/register\" -H 'Content-Type: application/json' -d @/tmp/admin_payload.json 2>/dev/null || echo 'error')
if echo \"\$RESPONSE\" | grep -qi 'token\\|user\\|success'; then
echo 'Usuario creado via API'
else
echo 'Intentando via base de datos...'
DOCKER_CMD=\$(docker ps &>/dev/null && echo 'docker' || echo 'sudo docker')
\$DOCKER_CMD exec openccb-db psql -U user -d openccb_cms -c \"
CREATE EXTENSION IF NOT EXISTS pgcrypto;
SELECT * FROM fn_register_user(
'$ADMIN_EMAIL',
crypt('$ADMIN_PASS', gen_salt('bf', 12)),
'$ADMIN_NAME',
'admin',
'$ORG_NAME'
);
\" 2>/dev/null && echo 'Usuario creado' || echo 'No se pudo crear'
fi
rm -f /tmp/admin_payload.json
fi
" 2>/dev/null || echo "No se pudo crear el usuario administrador"
rm -f /tmp/admin_payload.json
echo ""
echo "========================================"
echo " CREDENCIALES DE ACCESO"
echo "========================================"
echo ""
echo "URLs de acceso:"
echo " Studio - CMS: $PROTOCOL://studio.norteamericano.com"
echo " Experience - LMS: $PROTOCOL://learning.norteamericano.com"
echo ""
echo "Usuario Administrador:"
echo " Email: $ADMIN_EMAIL"
echo " Contraseña: $ADMIN_PASS"
echo ""
echo "Organizacion: $ORG_NAME"
echo ""
if [ "$PRESERVE_SSL_CERTS" = "true" ]; then
echo "✅ Certificados SSL existentes preservados"
echo " Los certificados ya están activos y funcionando"
elif [ "$LETSENCRYPT_STAGING" = "true" ]; then
echo "⚠️ Usando Let's Encrypt STAGING"
echo " Los certificados son de prueba - el navegador mostrara advertencias"
echo " Las APIs usan HTTP para evitar errores de SSL"
echo " Certificados se generaran en ~1 hora"
elif [ "$USE_SSL" = "y" ] || [ "$USE_SSL" = "Y" ]; then
echo "✅ Usando Let's Encrypt PRODUCTION"
echo " Certificados reales se generaran en 2-5 minutos"
else
echo "✅ Usando HTTP (sin SSL)"
fi
echo ""
echo "Credenciales de Base de Datos - GUARDAR EN LUGAR SEGURO:"
echo " DB_PASSWORD: $(grep "^DB_PASSWORD=" .env | cut -d"=" -f2)"
echo " JWT_SECRET: $(grep "^JWT_SECRET=" .env | cut -d"=" -f2)"
echo ""
echo "Comandos utiles:"
echo " sudo docker compose ps"
echo " docker logs acme-companion --tail 50"
echo " docker logs openccb-studio --tail 20"
echo " sudo docker compose restart"
echo ""
REMOTE_SCRIPT_CONTENT
# Copiar script al servidor
scp -i "$PEM_PATH" /tmp/remote-deploy.sh "$REMOTE_USER@$REMOTE_HOST:/tmp/openccb-remote.sh"
# Ejecutar script remoto
ssh -i "$PEM_PATH" "$REMOTE_USER@$REMOTE_HOST" "bash /tmp/openccb-remote.sh"
SCRIPT_EXIT=$?
# Limpiar archivo temporal
rm -f /tmp/remote-deploy.sh
ssh -i "$PEM_PATH" "$REMOTE_USER@$REMOTE_HOST" "rm -f /tmp/openccb-remote.sh"
echo ""
if [ $SCRIPT_EXIT -eq 0 ]; then
echo "===================================================="
echo " Despliegue Completado Exitosamente"
echo "===================================================="
echo ""
echo "Accede a tu plataforma:"
echo " Studio - CMS: $PROTOCOL://studio.norteamericano.com"
echo " Experience - LMS: $PROTOCOL://learning.norteamericano.com"
echo ""
echo "Conectate para administrar:"
echo " ssh -i \"$PEM_PATH\" $REMOTE_USER@$REMOTE_HOST"
echo " cd $REMOTE_PATH"
echo ""
echo "Para actualizar en el futuro:"
echo " Ejecuta: ./deploy.sh"
echo ""
else
echo "===================================================="
echo " Despliegue Completado con Errores"
echo "===================================================="
echo ""
echo "Error al ejecutar script remoto - codigo: $SCRIPT_EXIT"
echo ""
echo "Verifica manualmente:"
echo " ssh -i \"$PEM_PATH\" $REMOTE_USER@$REMOTE_HOST"
echo " cd $REMOTE_PATH"
echo " sudo docker compose ps"
echo " sudo docker compose logs"
echo ""
fi
exit $SCRIPT_EXIT