# Credenciales SQL Server (mismo usuario en todos los nodos salvo sql_password en database_nodes). # Si no defines PANEL_MSSQL_*, se usan DB_PRIMARY_* / DB_SECONDARY_* como respaldo. PANEL_MSSQL_USER=sa PANEL_MSSQL_PASSWORD=Clave.2025 # En contenedor Docker: reescribe localhost en server_name → host.docker.internal # PANEL_MSSQL_DOCKER=true # Depuración de bases duplicadas: tolerancia de tamaño (fracción 0–1) para marcar una base como # segura para borrar del servidor viejo. El nuevo debe pesar >= (1 - tolerancia) del viejo. Default 0.2. # PANEL_DEDUP_SIZE_TOLERANCE=0.2 # "Mandar al nuevo": carpeta donde el SQL viejo escribe el .bak (default: data_folder del servidor). # PANEL_DEDUP_BACKUP_FOLDER= # Ventana de verificación tras enviar (ms) antes de dar la base por "en tránsito". Default 180000. # PANEL_DEDUP_MOVE_VERIFY_TIMEOUT_MS=180000 # Intervalo de sondeo de la verificación (ms). Default 5000. # PANEL_DEDUP_MOVE_POLL_MS=5000 # requestTimeout de SQL Server para BACKUP/DROP (el default de node-mssql, 15 s, no alcanza para # bases reales). Default 3600000 (1 h). # PANEL_DEDUP_DDL_TIMEOUT_MS=3600000 # PostgreSQL - Usuarios del panel + catálogo ControlDesk (tablas a24c.* las crea otra app) DB_POSTGRES_HOST=localhost DB_POSTGRES_PORT=5434 DB_POSTGRES_USER=postgres DB_POSTGRES_PASS=Control. DB_POSTGRES_DB=CONTROLDESK # JWT Secret (cambiar en producción) JWT_SECRET=change-this-secret-in-production-please-use-a-long-random-string # Ruta de respaldos (LEGACY / fallback): carpeta única leída por la vista "Respaldos # Almacenados" y por /backup?file=... cuando no se especifica restaurador. Las vistas nuevas # "Respaldos Restaurados" y "Restores Fallidos" resuelven la carpeta de CADA restaurador de # forma relativa (derivada de la Entrada que reporta cada uno), sin usar esta variable. # Apúntala a una carpeta de procesados accesible por filesystem (local o share) si usas el modo legacy. BACKUP_PATH=D:/BackupSFTP/ # SMTP para envío de avisos de alertas críticas # Si SMTP_HOST está vacío los botones "Enviar avisos" no hacen nada (sin error). SMTP_HOST= SMTP_PORT=587 SMTP_USER= SMTP_PASSWORD= SMTP_FROM= SMTP_USE_TLS=true # Integración CloudRestoreAS # Token Bearer que CloudRestoreAS envía en Authorization: Bearer # para /api/restore/target-for, /api/restore/job-result y /api/restore/instance-config. # DEBE ser idéntico al valor "Token API del PANEL" en CloudRestoreAS (pestaña Config). # Generar uno largo y aleatorio, p. ej.: # node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" CLOUDRESTORE_API_TOKEN= # Clave compartida con a24c para cifrar la contraseña SQL de los nodos en reposo. # El panel cifra en Fernet (AES-128-CBC + HMAC) derivando la clave como sha256(SECRET_KEY), # EXACTAMENTE igual que a24c, para que a24c pueda descifrar database_nodes.sql_password. # ⚠️ DEBE ser idéntica a la SECRET_KEY del backend de a24c, o a24c no podrá conectar. SECRET_KEY= # [LEGADO] Clave AES-256 (32 bytes) del formato antiguo `gcm:` del panel. Solo se usa para # LEER credenciales cifradas antes de migrar a Fernet; las nuevas se escriben con SECRET_KEY. # Puede quedar vacía en instalaciones nuevas. Generar (si aplica) con: # node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" ENCRYPTION_KEY= # ============================================================================ # Distribución de versiones de CloudRestoreAS (pantalla /versiones-cras) # # Los binarios se publican en el registro de paquetes GENÉRICOS de Gitea desde el build # local del repo CloudRecoveryAS (`build-all.sh --publish`). El panel los descubre leyendo # esa API, los descarga verificando el sha256 que Gitea calcula, y los instala en cada # servidor de restauración por SSH/SFTP. # ============================================================================ # Instancia de Gitea y organización dueña del paquete. GITEA_BASE_URL=https://git.aduanasoft.com GITEA_OWNER=ADUANASOFT CRAS_PACKAGE_NAME=cloudrestoreas # PAT de Gitea. El panel solo LEE el registro, así que basta el scope `read:package`. # (El token con `write:package` vive en la máquina de build, no aquí.) # Sin este token /versiones-cras carga pero avisa que no puede sincronizar. # # El valor va DESNUDO: sin los `<>` de una plantilla, sin comillas y sin espacios. Compose los # pasa literales y Gitea responde 401, indistinguible de un token revocado. # Y tras cambiarlo hay que RECREAR el contenedor (`docker compose up -d`), no reiniciarlo: # `environment:` con `${VAR:-}` congela el valor al crearlo y `restart` no relee este archivo. GITEA_TOKEN= # Caché local de artefactos. Cada uno pesa ~270 MB y se publican dos por versión, así que la # carpeta crece ~540 MB por versión; CRAS_CACHE_KEEP_VERSIONS limita cuántas se conservan # (las versiones activas nunca se borran). CRAS_RELEASES_DIR=./local-cras-releases CRAS_CACHE_KEEP_VERSIONS=3 # Origen del bind-mount de esa caché en el HOST (docker-compose.prod.yml). Es una ruta del host, # no del contenedor, así que debe existir EN EL SISTEMA DEL HOST: en un host Windows # `C:/Aduanasoft/cras-releases`, en uno Linux `/srv/panel/cras-releases`. Una ruta estilo POSIX # en un host Windows no falla: Docker la crea dentro de su propia VM, donde nadie la ve ni la # respalda y consume el disco virtual. CRAS_RELEASES_HOST_PATH= # URL con la que el agente instalado reportará al panel. El instalador remoto la siembra en el # config/.env del servidor destino, así que TIENE que ser alcanzable desde esos servidores (no # localhost). Si se omite se usa ORIGIN. # # DEBE incluir el puerto si el panel no está detrás de un proxy en 443. El panel escucha en 3000, # y en cpanel-a24 el 443 lo sirve el PHP legado: sin el `:3000` el agente le pediría todo a otro # servicio y recibiría 404. Se siembra también al ACTUALIZAR, así que una URL mal puesta rompe # un agente que ya funcionaba. Lo más seguro es dejarla vacía y que tome ORIGIN. PANEL_PUBLIC_URL=