# Instalación cPanel - código base 1.2.0 + parche mysql8045-r1 / estándar 2.2

Fecha: 19-10-2026. PHP web y CLI 8.4.x. ZIP completo: vendor y activos compilados incluidos. ZIP Terminal: omite vendor y lo instala con Composer; conserva activos y paquetes internos.

## Dominios y estructura

| Aplicación | Extraer directamente en | Document Root |
| --- | --- | --- |
| Cliente pruebas | /home/ticserv1/norteintegra.ticservicios.cl/ | /home/ticserv1/norteintegra.ticservicios.cl/public |
| Central permanente | /home/ticserv1/licences.ticservicios.cl/ | /home/ticserv1/licences.ticservicios.cl/public |

Los ZIP cPanel no contienen apps/ ni carpeta exterior. En su raíz están artisan, instalar.sh, instalar.php, cron.php, public/, vendor/ y el resto de Laravel. packages/ son fuentes internas; no otra aplicación. El ZIP fuente conserva apps/ para desarrollar ambas aplicaciones.

No mezclar estructuras antiguas: preparar un destino privado limpio y conservar .env, APP_KEY y storage de la misma aplicación. Confirmar public/index.php y cambiar Document Root en cPanel > Dominios > Administrar. Si el proveedor limita esa función, debe ajustarla él. Nunca publicar todo Laravel ni mover index.php a la raíz privada.

## Requisitos

PHP 8.4.x web y CLI; ctype, curl, dom, fileinfo, filter, hash, mbstring, openssl, pcre, pdo, pdo_mysql, session, sodium, tokenizer, xml; MySQL Community Server >= 8.0.45 (incluye 8.0.45-cll-lve), posteriores con homologación; HTTPS; terminal; cron cada minuto; salida HTTPS y SMTP. MariaDB y otros motores no MySQL no están homologados; MySQL 8.0 recibe solo Sustaining Support de Oracle y se recomienda migrar a LTS cuando el hosting lo permita. PHP, extensiones, servicio MySQL y certificado los aporta el hosting.

## Primera instalación

1. Crear BD y usuario exclusivos por aplicación y asignar privilegios sobre su propia BD.
2. Extraer ZIP conservando archivos ocultos; configurar Document Root a public/ y PHP web 8.4.
3. Copiar .env.example a .env en raíz Laravel. Completar APP_NAME, APP_URL, DB_*, MAIL_* y SESSION_COOKIE. APP_URL es el origen HTTPS exacto sin /public. APP_KEY vacía solo en una BD nueva sin tablas.
4. Ejecutar primero central y después cliente:

```bash
cd /home/ticserv1/licences.ticservicios.cl
bash instalar.sh --check
bash instalar.sh
```

```bash
cd /home/ticserv1/norteintegra.ticservicios.cl
bash instalar.sh --check
bash instalar.sh
```

El instalador detecta PHP 8.4 CLI y admite desde MySQL 8.0.45 (la validación de versión no reemplaza pruebas de migraciones); genera claves ausentes solo cuando corresponde, migra, prepara permisos/propietario y cachés. En central genera la primera clave firmante si no existe. Conserva claves, datos e identidad. Una BD con tablas y sin APP_KEY se detiene para recuperarla.

Si no detecta PHP, usar la ruta confirmada por proveedor (el ejemplo EasyApache puede variar):

```bash
UNIVERSAL_PHP_BIN=/opt/cpanel/ea-php84/root/usr/bin/php bash instalar.sh
```

5. Configurar cron cada minuto con el comando impreso. En cPanel el campo Comando incluye PHP y cron.php, sin los cinco asteriscos. cron.php evita solapamientos y rota scheduler-YYYY-MM-DD.log durante 14 días. Revisar vencimientos locales cada minuto no consulta la licencia cada minuto.
6. Abrir dominio limpio y /login. Configurar MFA central y custodiar recuperación. Verificar SMTP real. No hay contraseña predeterminada.

## Alternativa ZIP Terminal

Solo si elegiste _Terminal_, ejecutar antes del instalador desde raíz Laravel:

```bash
/RUTA/REAL/php84 /RUTA/REAL/composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-interaction
/RUTA/REAL/php84 /RUTA/REAL/composer.phar check-platform-reqs --no-dev
```

Composer debe estar disponible mediante el procedimiento oficial verificado del proveedor. No composer update ni --ignore-platform-reqs en producción. El ZIP completo no necesita Composer, Node ni npm; los activos ya vienen compilados en ambas variantes.

## Personalizar por dominio

| Parámetro | Acción |
| --- | --- |
| APP_NAME / APP_URL | Nombre y origen HTTPS exacto |
| APP_ENV / APP_DEBUG | production / false |
| APP_KEY | Automática una vez; exclusiva, preservar y respaldar |
| DB_* | BD, usuario, clave, host y puerto reales |
| SESSION_COOKIE / SESSION_DOMAIN | Nombre exclusivo; dominio vacío por defecto |
| MAIL_* | SMTP/remitente reales; MAIL_TIMEOUT=15; esquema según proveedor |
| LOG_CHANNEL / LOG_DAILY_DAYS | daily / 14; retención según negocio |
| TRUSTED_PROXIES | Vacío sin proxy; IP/CIDR explícitos confirmados por proveedor, separados por comas |
| OPS_HEALTH_TOKEN | Se genera; secreto independiente para monitor |
| LICENSE_SERVER_URL | Cliente: https://licences.ticservicios.cl/api/v1 |
| LICENSE_PRODUCT_CODE | Producto registrado en central |
| LICENSE_DOMAIN_PROOF | Prueba propia de la instalación |
| LICENSE_PUBLIC_KEYS | JSON de claves públicas centrales confiables |

Tras cambiar .env repetir bash instalar.sh para recargar cachés. No compartir .env. TRUSTED_PROXIES reconoce IP/esquema/puerto, sin confiar en X-Forwarded-Host; no admite comodines ni CIDR /0. Nunca desactivar HTTPS para ocultar el 400.

## Activación

Crear cliente/producto en central. En cliente abrir /license y registrar su UUID y origen en central. Copiar prueba de dominio y claves públicas al .env cliente; repetir instalador. Verificar dominio, emitir código y canjear en /license. La licencia firmada/cifrada queda en MySQL local; la navegación no consulta al central.

Permisos en /access: crear roles, permisos custom.* y asignar a usuarios. Cada permiso creado debe ser utilizado por una Policy/Gate o servicio de la funcionalidad. No concede acceso por existir en BD.

## Validar y operar

Comprobar /login, /up, activos, cookies, SMTP, permisos, cron y activación/suspensión/reactivación. /api/ops/v1/health con Bearer OPS_HEALTH_TOKEN confirma BD y heartbeat; /up solo arranque. Rutas privadas no deben exponer contenido. Respaldar fuera del servidor y probar restauración.

403/404: raíz, .htaccess, permisos y rewrite. 400: APP_URL efectivo y TLS/proxy; determinar causa con evidencia. 500: logs privados, APP_KEY, SQL e instalación. Mantener APP_DEBUG=false. No editar vendor ni platform_check.php.

Actualizar: staging y respaldo .env/APP_KEY/BD/storage; desplegar código/vendor coherentes; conservar datos; ejecutar instalador; aceptar antes de reabrir. No migrate:fresh ni key:generate con datos existentes. Restauración cliente: licensing:mark-restored y licensing:check --force antes de abrir.

Desarrollar con ZIP fuente y docs/DEVELOPMENT.md. packages/ es la fuente; Composer copia a vendor. Módulos nuevos comparten casos de uso y deben comprobar permisos/licencia en HTTP, API, jobs y consola. Flutter y sincronización offline de negocio se implementan por proyecto.

## Nota de compatibilidad MySQL 8.0.45

El script `bash instalar.sh --check` permite comprobar motor y configuración sin modificar datos **si ya existe `.env`**. Si falta `.env`, `--check` informa el requisito y no crea archivos. Después de la comprobación ejecutar instalaciones y migraciones en una BD nueva de prueba. No asumir que cualquier versión futura que pasa el comparador ha sido certificada. El puerto/host MySQL deben corresponder a la cuenta y el soporte de PHP `pdo_mysql` es obligatorio.
