#!/bin/bash # Script de gestión Docker para SIDEL ScriptsManager # Compatible con las especificaciones del proyecto # Uso: ./docker-manage.sh [comando] set -e # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' # No Color # Variables del proyecto SIDEL SIDEL_APP_PORT=5002 SIDEL_DEV_PORT=5003 SIDEL_SCRIPT_PORT_RANGE="5200-5400" SIDEL_CONTAINER_NAME="sidel_scriptsmanager" SIDEL_DEV_CONTAINER_NAME="sidel_scriptsmanager_dev" # Función para mostrar banner SIDEL show_banner() { echo -e "${BLUE}================================================================${NC}" echo -e "${BLUE} SIDEL ScriptsManager - Docker Management ${NC}" echo -e "${BLUE}================================================================${NC}" echo -e "${PURPLE}Multi-User Script Manager with Conda Environments${NC}" echo -e "${PURPLE}Frontend Port: ${SIDEL_APP_PORT} | Script Ports: ${SIDEL_SCRIPT_PORT_RANGE}${NC}" echo -e "${BLUE}================================================================${NC}" echo "" } # Función para mostrar flujo de trabajo de rebuild show_rebuild_workflow() { show_banner echo -e "${BLUE}🔄 Flujo de Trabajo para Cambios${NC}" echo -e "${YELLOW}═══════════════════════════════${NC}" echo echo -e "${BLUE}📁 CAMBIOS QUE NO REQUIEREN REBUILD:${NC}" echo " • Scripts en app/backend/script_groups/" echo " • Configuraciones en app/config/" echo " • Templates HTML en app/templates/" echo " • Archivos estáticos (CSS, JS)" echo echo -e "${GREEN} Comando:${NC} sudo ./docker-manage.sh restart" echo echo -e "${BLUE}🏗️ CAMBIOS QUE REQUIEREN REBUILD:${NC}" echo " • requirements.txt o requirements-dev.txt" echo " • Dockerfile" echo " • Nuevos entornos conda" echo " • Dependencies de entornos existentes" echo echo -e "${GREEN} Comandos:${NC}" echo " sudo ./docker-manage.sh stop" echo " sudo ./docker-manage.sh build" echo " sudo ./docker-manage.sh start" echo echo -e "${BLUE}⚡ REBUILD RÁPIDO:${NC}" echo -e "${GREEN} sudo ./docker-manage.sh rebuild${NC}" echo echo -e "${BLUE}📋 VERIFICAR DESPUÉS:${NC}" echo " sudo ./verify-environments.sh" echo " sudo ./docker-manage.sh envs" echo } # Función para rebuild rápido rebuild_quick() { show_banner echo -e "${BLUE}⚡ Rebuild rápido de SIDEL ScriptsManager...${NC}" echo -e "${YELLOW}Paso 1/3: Deteniendo contenedor...${NC}" stop_containers echo -e "${YELLOW}Paso 2/3: Reconstruyendo imagen...${NC}" build_image echo -e "${YELLOW}Paso 3/3: Iniciando servicios...${NC}" start_production echo -e "${GREEN}✅ Rebuild completado exitosamente${NC}" echo -e "${BLUE}🔍 Ejecuta: sudo ./verify-environments.sh para verificar${NC}" } # Función para mostrar ayuda de flujo de trabajo show_help() { show_banner echo "Uso: $0 [comando]" echo "" echo "Comandos disponibles:" echo -e " ${GREEN}build${NC} Construir la imagen Docker" echo -e " ${GREEN}start${NC} Iniciar SIDEL ScriptsManager en producción" echo -e " ${GREEN}start-dev${NC} Iniciar en modo desarrollo con hot-reload" echo -e " ${GREEN}start-backup${NC} Iniciar servicio de backup automático" echo -e " ${GREEN}start-monitoring${NC} Iniciar servicio de monitoreo de logs" echo -e " ${GREEN}stop${NC} Detener todos los contenedores" echo -e " ${GREEN}restart${NC} Reiniciar el contenedor principal" echo -e " ${GREEN}logs${NC} Mostrar logs del contenedor principal" echo -e " ${GREEN}logs-dev${NC} Mostrar logs del contenedor de desarrollo" echo -e " ${GREEN}shell${NC} Abrir shell en el contenedor principal" echo -e " ${GREEN}shell-dev${NC} Abrir shell en el contenedor de desarrollo" echo -e " ${GREEN}backup${NC} Ejecutar backup manual del sistema" echo -e " ${GREEN}clean${NC} Limpiar contenedores e imágenes no utilizadas" echo -e " ${GREEN}reset${NC} Resetear completamente (¡CUIDADO: Borra datos!)" echo -e " ${GREEN}status${NC} Mostrar estado de los contenedores" echo -e " ${GREEN}envs${NC} Listar entornos conda disponibles" echo -e " ${GREEN}rebuild${NC} Rebuild rápido (stop + build + start)" echo -e " ${GREEN}workflow${NC} Mostrar flujo de trabajo para cambios" echo -e " ${GREEN}health${NC} Verificar salud de la aplicación" echo -e " ${GREEN}init-db${NC} Inicializar base de datos SIDEL" echo -e " ${GREEN}verify${NC} Verificar configuración y entornos" echo -e " ${GREEN}ports${NC} Mostrar puertos en uso" echo -e " ${GREEN}users${NC} Gestionar usuarios (requiere shell activo)" echo -e " ${GREEN}db-status${NC} Verificar estado de la base de datos" echo -e " ${GREEN}db-migrate${NC} Migrar desde SQLite a PostgreSQL" echo -e " ${GREEN}db-backup${NC} Crear backup de la base de datos" echo -e " ${GREEN}start-postgres${NC} Iniciar solo el servicio PostgreSQL" echo -e " ${GREEN}stop-postgres${NC} Detener solo el servicio PostgreSQL" echo "" echo "Servicios opcionales (perfiles):" echo -e " ${YELLOW}--profile dev${NC} Modo desarrollo" echo -e " ${YELLOW}--profile production${NC} Modo producción" echo -e " ${YELLOW}--profile backup${NC} Backup automático" echo -e " ${YELLOW}--profile monitoring${NC} Monitoreo de logs" echo "" echo "Ejemplos:" echo " $0 build && $0 start" echo " $0 start-dev" echo " $0 logs -f" echo " $0 verify" } # Función para verificar si docker-compose está disponible check_docker_compose() { # Verificar permisos de Docker primero if ! docker ps &> /dev/null; then echo -e "${RED}Error: No tienes permisos para acceder a Docker${NC}" echo -e "${YELLOW}Soluciones posibles:${NC}" echo "1. Reinicia tu terminal/WSL después de agregar tu usuario al grupo docker" echo "2. O ejecuta: sudo usermod -aG docker \$USER && newgrp docker" echo "3. O usa sudo: sudo ./docker-manage.sh [comando]" echo "4. O ejecuta: su - \$USER (para recargar grupos)" exit 1 fi if command -v docker-compose &> /dev/null; then DOCKER_COMPOSE="docker-compose" elif docker compose version &> /dev/null; then DOCKER_COMPOSE="docker compose" else echo -e "${RED}Error: docker-compose no está disponible${NC}" echo -e "${YELLOW}Instalando docker-compose...${NC}" # Intentar instalar docker-compose if command -v apt &> /dev/null; then sudo apt update && sudo apt install -y docker-compose elif command -v yum &> /dev/null; then sudo yum install -y docker-compose else echo "Por favor instala docker-compose manualmente" exit 1 fi # Verificar nuevamente if command -v docker-compose &> /dev/null; then DOCKER_COMPOSE="docker-compose" else exit 1 fi fi } # Función para construir la imagen build_image() { show_banner echo -e "${BLUE}Construyendo imagen Docker para SIDEL ScriptsManager...${NC}" check_docker_compose # Verificar estructura de directorios antes de construir if [ -d "backend/script_groups" ]; then echo -e "${RED}❌ ERROR: Encontrado directorio incorrecto 'backend/script_groups/'${NC}" echo -e "${RED} Según especificaciones SIDEL, los scripts deben estar en 'app/backend/script_groups/' únicamente${NC}" exit 1 fi if [ ! -d "app/backend/script_groups" ]; then echo -e "${YELLOW}⚠️ Creando directorio app/backend/script_groups/...${NC}" mkdir -p app/backend/script_groups/hammer mkdir -p app/backend/script_groups/data_processing mkdir -p app/backend/script_groups/system_utilities fi $DOCKER_COMPOSE build scriptsmanager echo -e "${GREEN}✅ Imagen SIDEL ScriptsManager construida exitosamente${NC}" } # Función para iniciar en producción start_production() { show_banner echo -e "${BLUE}Iniciando SIDEL ScriptsManager en modo producción...${NC}" check_docker_compose # Crear directorios necesarios según especificaciones SIDEL echo -e "${BLUE}Preparando estructura de directorios...${NC}" mkdir -p data/script_groups data/system mkdir -p logs/executions logs/system logs/audit mkdir -p backup/daily mkdir -p instance # Copiar archivo de entorno si no existe if [ ! -f .env ]; then echo -e "${YELLOW}Creando archivo .env desde .env.example${NC}" cp .env.example .env echo -e "${YELLOW}¡IMPORTANTE: Edita el archivo .env con tus configuraciones de producción!${NC}" fi # Iniciar PostgreSQL primero echo -e "${BLUE}🐘 Iniciando PostgreSQL...${NC}" $DOCKER_COMPOSE up -d postgres # Esperar que PostgreSQL esté listo echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" sleep 10 # Iniciar aplicación echo -e "${BLUE}🚀 Iniciando aplicación...${NC}" $DOCKER_COMPOSE --profile production up -d scriptsmanager echo -e "${GREEN}✅ SIDEL ScriptsManager iniciado en http://localhost:${SIDEL_APP_PORT}${NC}" echo -e "${BLUE}📊 Dashboard multiusuario disponible${NC}" echo -e "${BLUE}🔧 Scripts TSNet en puertos ${SIDEL_SCRIPT_PORT_RANGE}${NC}" echo -e "${BLUE}🐘 PostgreSQL en puerto 5432${NC}" } # Función para iniciar en desarrollo start_development() { show_banner echo -e "${BLUE}Iniciando SIDEL ScriptsManager en modo desarrollo...${NC}" check_docker_compose mkdir -p data/script_groups data/system mkdir -p logs/executions logs/system logs/audit mkdir -p backup/daily if [ ! -f .env ]; then cp .env.example .env fi # Iniciar PostgreSQL primero echo -e "${BLUE}🐘 Iniciando PostgreSQL...${NC}" $DOCKER_COMPOSE up -d postgres # Esperar que PostgreSQL esté listo echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" sleep 10 # Iniciar aplicación en modo desarrollo echo -e "${BLUE}🚀 Iniciando aplicación en modo desarrollo...${NC}" $DOCKER_COMPOSE --profile dev up -d scriptsmanager-dev echo -e "${GREEN}✅ SIDEL ScriptsManager (desarrollo) iniciado en http://localhost:${SIDEL_DEV_PORT}${NC}" echo -e "${BLUE}🔄 Hot-reload activado para desarrollo${NC}" echo -e "${BLUE}🐘 PostgreSQL en puerto 5432${NC}" } # Función para iniciar backup automático start_backup_service() { show_banner echo -e "${BLUE}Iniciando servicio de backup automático...${NC}" check_docker_compose $DOCKER_COMPOSE --profile backup up -d backup echo -e "${GREEN}✅ Servicio de backup automático iniciado${NC}" echo -e "${BLUE}📦 Backups diarios programados${NC}" } # Función para iniciar monitoreo start_monitoring() { show_banner echo -e "${BLUE}Iniciando servicio de monitoreo de logs...${NC}" check_docker_compose $DOCKER_COMPOSE --profile monitoring up -d log-monitor echo -e "${GREEN}✅ Servicio de monitoreo iniciado${NC}" echo -e "${BLUE}📊 Monitoreo de logs multiusuario activado${NC}" } # Función para detener contenedores stop_containers() { echo -e "${BLUE}Deteniendo contenedores...${NC}" check_docker_compose $DOCKER_COMPOSE down echo -e "${GREEN}Contenedores detenidos${NC}" } # Función para reiniciar restart_container() { echo -e "${BLUE}Reiniciando contenedor principal...${NC}" check_docker_compose $DOCKER_COMPOSE restart scriptsmanager echo -e "${GREEN}Contenedor reiniciado${NC}" } # Función para mostrar logs show_logs() { check_docker_compose $DOCKER_COMPOSE logs "${@:2}" scriptsmanager } # Función para mostrar logs de desarrollo show_dev_logs() { check_docker_compose $DOCKER_COMPOSE logs "${@:2}" scriptsmanager-dev } # Función para abrir shell open_shell() { check_docker_compose echo -e "${BLUE}Abriendo shell en el contenedor...${NC}" $DOCKER_COMPOSE exec scriptsmanager bash } # Función para abrir shell de desarrollo open_dev_shell() { check_docker_compose echo -e "${BLUE}Abriendo shell en el contenedor de desarrollo...${NC}" $DOCKER_COMPOSE exec scriptsmanager-dev bash } # Función para backup manual manual_backup() { echo -e "${BLUE}Ejecutando backup manual...${NC}" check_docker_compose $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python -c 'from app.services.backup_service import BackupService; BackupService().create_backup()'" echo -e "${GREEN}Backup completado${NC}" } # Función para limpiar Docker clean_docker() { echo -e "${YELLOW}Limpiando contenedores e imágenes no utilizadas...${NC}" docker system prune -f echo -e "${GREEN}Limpieza completada${NC}" } # Función para reset completo reset_all() { echo -e "${RED}¡ADVERTENCIA! Esto eliminará todos los datos y contenedores.${NC}" read -p "¿Estás seguro? (escribe 'yes' para continuar): " -r if [[ $REPLY == "yes" ]]; then check_docker_compose $DOCKER_COMPOSE down -v docker system prune -af sudo rm -rf data/* backup/* logs/* echo -e "${GREEN}Reset completado${NC}" else echo -e "${YELLOW}Operación cancelada${NC}" fi } # Función para mostrar estado show_status() { echo -e "${BLUE}Estado de los contenedores:${NC}" check_docker_compose $DOCKER_COMPOSE ps } # Función para listar entornos conda list_conda_envs() { echo -e "${BLUE}Entornos conda disponibles:${NC}" check_docker_compose $DOCKER_COMPOSE exec scriptsmanager bash -c "conda env list" } # Función para verificar salud health_check() { echo -e "${BLUE}Verificando salud de SIDEL ScriptsManager...${NC}" if curl -f http://localhost:${SIDEL_APP_PORT}/health >/dev/null 2>&1; then echo -e "${GREEN}✓ Aplicación saludable en puerto ${SIDEL_APP_PORT}${NC}" else echo -e "${RED}✗ Aplicación no responde en puerto ${SIDEL_APP_PORT}${NC}" exit 1 fi } # Función para inicializar base de datos SIDEL init_database() { show_banner echo -e "${BLUE}Inicializando base de datos SIDEL ScriptsManager...${NC}" check_docker_compose if ! docker ps | grep -q $SIDEL_CONTAINER_NAME; then echo -e "${YELLOW}Contenedor no está ejecutándose. Iniciando temporalmente...${NC}" $DOCKER_COMPOSE up -d scriptsmanager sleep 10 fi $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python scripts/init_sidel_db.py" echo -e "${GREEN}✅ Base de datos SIDEL inicializada${NC}" } # Función para verificar configuración completa verify_configuration() { show_banner echo -e "${BLUE}Verificando configuración SIDEL ScriptsManager...${NC}" echo -e "${BLUE}📁 Verificando estructura de directorios...${NC}" # Verificar directorios críticos if [ ! -d "app/backend/script_groups" ]; then echo -e "${RED}❌ app/backend/script_groups/ no encontrado${NC}" return 1 else echo -e "${GREEN}✅ app/backend/script_groups/ correcto${NC}" fi if [ -d "backend/script_groups" ]; then echo -e "${RED}❌ backend/script_groups/ existe (NO debería existir)${NC}" return 1 else echo -e "${GREEN}✅ backend/script_groups/ no existe (correcto)${NC}" fi # Verificar archivos de configuración if [ -f "requirements.txt" ]; then echo -e "${GREEN}✅ requirements.txt encontrado${NC}" else echo -e "${RED}❌ requirements.txt no encontrado${NC}" fi if [ -f "app/backend/script_groups/hammer/requirements.txt" ]; then echo -e "${GREEN}✅ TSNet requirements.txt encontrado${NC}" else echo -e "${RED}❌ TSNet requirements.txt no encontrado${NC}" fi # Verificar contenedor si está ejecutándose if docker ps | grep -q $SIDEL_CONTAINER_NAME; then echo -e "${BLUE}🐳 Verificando entornos conda en contenedor...${NC}" # Verificar entornos conda echo -e "${BLUE}📋 Entornos conda disponibles:${NC}" $DOCKER_COMPOSE exec scriptsmanager conda env list echo -e "${BLUE}🔍 Verificando paquetes en entorno scriptsmanager:${NC}" $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python -c 'import flask, flask_socketio; print(f\"Flask: {flask.__version__}, SocketIO: {flask_socketio.__version__}\")'" echo -e "${BLUE}🔍 Verificando paquetes en entorno tsnet:${NC}" $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate tsnet && python -c 'import numpy, matplotlib; print(f\"NumPy: {numpy.__version__}, Matplotlib: {matplotlib.__version__}\")'" # Verificar puertos echo -e "${BLUE}🔌 Verificando puertos:${NC}" if curl -s http://localhost:${SIDEL_APP_PORT} >/dev/null; then echo -e "${GREEN}✅ Puerto ${SIDEL_APP_PORT} (frontend) accesible${NC}" else echo -e "${YELLOW}⚠️ Puerto ${SIDEL_APP_PORT} (frontend) no accesible${NC}" fi else echo -e "${YELLOW}⚠️ Contenedor no está ejecutándose${NC}" echo -e "${BLUE}💡 Ejecuta: $0 start${NC}" fi echo -e "${GREEN}✅ Verificación completada${NC}" } # Función para mostrar puertos en uso show_ports() { show_banner echo -e "${BLUE}Estado de puertos SIDEL ScriptsManager:${NC}" echo "" echo -e "${BLUE}Puerto Frontend:${NC} ${SIDEL_APP_PORT}" echo -e "${BLUE}Puerto Desarrollo:${NC} ${SIDEL_DEV_PORT}" echo -e "${BLUE}Rango Scripts:${NC} ${SIDEL_SCRIPT_PORT_RANGE}" echo "" if command -v netstat >/dev/null 2>&1; then echo -e "${BLUE}Puertos actualmente en uso:${NC}" netstat -tlnp 2>/dev/null | grep -E ":(5002|5003|520[0-9]|53[0-9][0-9]|5400)" || echo "Ningún puerto SIDEL en uso" elif command -v ss >/dev/null 2>&1; then echo -e "${BLUE}Puertos actualmente en uso:${NC}" ss -tlnp | grep -E ":(5002|5003|520[0-9]|53[0-9][0-9]|5400)" || echo "Ningún puerto SIDEL en uso" else echo -e "${YELLOW}⚠️ netstat/ss no disponible para verificar puertos${NC}" fi } # Función para gestión de usuarios manage_users() { show_banner echo -e "${BLUE}Gestión de usuarios SIDEL ScriptsManager${NC}" if ! docker ps | grep -q $SIDEL_CONTAINER_NAME; then echo -e "${RED}❌ El contenedor no está ejecutándose${NC}" echo -e "${BLUE}💡 Ejecuta: $0 start${NC}" return 1 fi echo -e "${BLUE}Abriendo shell para gestión de usuarios...${NC}" echo -e "${YELLOW}Comandos útiles:${NC}" echo " - python scripts/create_admin.py --username --password " echo " - python scripts/list_users.py" echo " - python scripts/manage_users.py" echo "" $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && bash" } # Función para verificar estado de la base de datos check_database_status() { show_banner echo -e "${BLUE}Verificando estado de la base de datos...${NC}" check_docker_compose # Verificar si PostgreSQL está ejecutándose if docker ps | grep -q "scriptsmanager_postgres"; then echo -e "${GREEN}✅ PostgreSQL container is running${NC}" # Verificar conectividad if $DOCKER_COMPOSE exec postgres pg_isready -U scriptsmanager -d scriptsmanager > /dev/null 2>&1; then echo -e "${GREEN}✅ PostgreSQL is accepting connections${NC}" # Obtener información de la base de datos echo -e "${BLUE}📊 Database Information:${NC}" $DOCKER_COMPOSE exec postgres psql -U scriptsmanager -d scriptsmanager -c " SELECT 'PostgreSQL Version' as info, version() as value UNION ALL SELECT 'Database Size' as info, pg_size_pretty(pg_database_size('scriptsmanager')) as value UNION ALL SELECT 'Active Connections' as info, count(*)::text as value FROM pg_stat_activity WHERE datname = 'scriptsmanager';" 2>/dev/null || echo "Could not retrieve database info" else echo -e "${RED}❌ PostgreSQL is not accepting connections${NC}" fi else echo -e "${YELLOW}⚠️ PostgreSQL container is not running${NC}" echo -e "${BLUE}💡 Start with: $0 start-postgres${NC}" fi # Verificar si la aplicación puede conectarse if docker ps | grep -q $SIDEL_CONTAINER_NAME; then echo -e "${BLUE}🔗 Testing application database connection...${NC}" $DOCKER_COMPOSE exec scriptsmanager bash -c " source activate scriptsmanager && python -c 'from app.config.database import check_db_health; import json; print(json.dumps(check_db_health(), indent=2))' " 2>/dev/null || echo -e "${YELLOW}⚠️ Application container not available${NC}" fi } # Función para migrar de SQLite a PostgreSQL migrate_to_postgresql() { show_banner echo -e "${BLUE}Migrando desde SQLite a PostgreSQL...${NC}" check_docker_compose # Verificar que PostgreSQL esté ejecutándose if ! docker ps | grep -q "scriptsmanager_postgres"; then echo -e "${YELLOW}Iniciando PostgreSQL...${NC}" $DOCKER_COMPOSE up -d postgres sleep 10 fi # Verificar si existe la base de datos SQLite if [ ! -f "data/scriptsmanager.db" ]; then echo -e "${RED}❌ No se encontró la base de datos SQLite en data/scriptsmanager.db${NC}" echo -e "${BLUE}💡 ¿Quizás ya se migró o no tienes datos existentes?${NC}" return 1 fi echo -e "${BLUE}🔄 Ejecutando migración...${NC}" echo -e "${YELLOW}Esto puede tomar varios minutos dependiendo del tamaño de los datos${NC}" # Ejecutar el script de migración python migrate_sqlite_to_postgresql.py \ --source "data/scriptsmanager.db" \ --target "${DATABASE_URL:-postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager}" \ --backup if [ $? -eq 0 ]; then echo -e "${GREEN}✅ Migración completada exitosamente${NC}" echo -e "${BLUE}💡 La base de datos SQLite original se mantiene como backup${NC}" echo -e "${BLUE}💡 Ahora puedes usar PostgreSQL configurando DATABASE_URL en docker-compose.yml${NC}" else echo -e "${RED}❌ La migración falló${NC}" return 1 fi } # Función para backup de base de datos backup_database() { show_banner echo -e "${BLUE}Creando backup de la base de datos...${NC}" check_docker_compose if docker ps | grep -q "scriptsmanager_postgres"; then # Backup PostgreSQL echo -e "${BLUE}📦 Creando backup de PostgreSQL...${NC}" timestamp=$(date +"%Y%m%d_%H%M%S") backup_file="backup/postgres_backup_${timestamp}.sql" mkdir -p backup $DOCKER_COMPOSE exec postgres pg_dump -U scriptsmanager -d scriptsmanager > "$backup_file" if [ $? -eq 0 ]; then echo -e "${GREEN}✅ Backup PostgreSQL creado: ${backup_file}${NC}" else echo -e "${RED}❌ Error creando backup PostgreSQL${NC}" fi elif [ -f "data/scriptsmanager.db" ]; then # Backup SQLite echo -e "${BLUE}📦 Creando backup de SQLite...${NC}" timestamp=$(date +"%Y%m%d_%H%M%S") backup_file="backup/sqlite_backup_${timestamp}.db" mkdir -p backup cp "data/scriptsmanager.db" "$backup_file" echo -e "${GREEN}✅ Backup SQLite creado: ${backup_file}${NC}" else echo -e "${RED}❌ No se encontró ninguna base de datos para hacer backup${NC}" fi } # Función para iniciar solo PostgreSQL start_postgres() { show_banner echo -e "${BLUE}Iniciando servicio PostgreSQL...${NC}" check_docker_compose $DOCKER_COMPOSE up -d postgres echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" sleep 5 if $DOCKER_COMPOSE exec postgres pg_isready -U scriptsmanager -d scriptsmanager > /dev/null 2>&1; then echo -e "${GREEN}✅ PostgreSQL iniciado y listo en puerto 5432${NC}" echo -e "${BLUE}🔗 Connection: postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager${NC}" else echo -e "${YELLOW}⚠️ PostgreSQL iniciado pero aún no está listo${NC}" echo -e "${BLUE}💡 Usa: $0 db-status para verificar${NC}" fi } # Función para detener solo PostgreSQL stop_postgres() { echo -e "${BLUE}Deteniendo servicio PostgreSQL...${NC}" check_docker_compose $DOCKER_COMPOSE stop postgres echo -e "${GREEN}✅ PostgreSQL detenido${NC}" } # Script principal case "${1:-help}" in build) build_image ;; start) start_production ;; start-dev) start_development ;; start-backup) start_backup_service ;; start-monitoring) start_monitoring ;; stop) stop_containers ;; restart) restart_container ;; logs) show_logs "$@" ;; logs-dev) show_dev_logs "$@" ;; shell) open_shell ;; shell-dev) open_dev_shell ;; backup) manual_backup ;; clean) clean_docker ;; reset) reset_all ;; status) show_status ;; envs) list_conda_envs ;; rebuild) rebuild_quick ;; workflow) show_rebuild_workflow ;; health) health_check ;; init-db) init_database ;; verify) verify_configuration ;; ports) show_ports ;; users) manage_users ;; db-status) check_database_status ;; db-migrate) migrate_to_postgresql ;; db-backup) backup_database ;; start-postgres) start_postgres ;; stop-postgres) stop_postgres ;; help|--help|-h) show_help ;; *) echo -e "${RED}Comando desconocido: $1${NC}" show_help exit 1 ;; esac