#!/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 ayuda 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}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 "" echo "Servicios opcionales (perfiles):" echo -e " ${YELLOW}--profile dev${NC} Modo desarrollo" 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 $DOCKER_COMPOSE 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}" } # 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 $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}" } # 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" } # 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 ;; health) health_check ;; init-db) init_database ;; verify) verify_configuration ;; ports) show_ports ;; users) manage_users ;; help|--help|-h) show_help ;; *) echo -e "${RED}Comando desconocido: $1${NC}" show_help exit 1 ;; esac