# Despliegue en hosting con cPanel / WHM

Guía para publicar el Sistema Integral de Proveeduría Municipal en hosting compartido o
semi-dedicado con cPanel, Plesk o WHM. Cubre la creación del dominio, la base de datos,
los permisos, el `.htaccess` y el respaldo programado.

---

## 1. Elementos que se necesitan del administrador del hosting

| Elemento | Dónde se consigue |
|---|---|
| Dominio o subdominio | Panel del hosting (ej. `proveeduria.municipio.gob.mx`) |
| Acceso FTP o SSH | Panel del hosting |
| Base de datos MySQL y usuario | cPanel → **MySQL® Databases** |
| Versión de PHP seleccionable | cPanel → **Select PHP Version** (8.2 o superior) |
| Extensiones PHP habilitadas | cPanel → **Select PHP Version → Extensions** |
| Soporte para SSL | cPanel → **SSL/TLS Status** (Let's Encrypt) |

Extensiones necesarias: `pdo_mysql`, `mbstring`, `dom`, `fileinfo`, `openssl`, `json`.
Recomendadas: `gd`, `zip`.

---

## 2. Crear la base de datos

En cPanel → **MySQL® Databases**:

1. **Create New Database**: nombre `proveeduria` (cPanel añade el prefijo de la cuenta,
   por ejemplo `cpuser_proveeduria`). Anote el nombre completo.
2. **Create New User**: usuario `proveeduria` con una contraseña larga y aleatoria.
3. **Add User To Database**: marque el usuario y la base, y marque **ALL PRIVILEGES**.

Anote los tres datos: **base de datos completa**, **usuario** y **contraseña**. La contraseña se escribe en el paso 2 del instalador.

---

## 3. Subir el sistema

### Opción A — Administrador de archivos (sin SSH)

1. Comprime el proyecto en un `.zip`. **No** incluya la carpeta `vendor/` si va a ejecutar
   `composer install` por SSH; si no tiene SSH, inclúyala.
2. En cPanel → **File Manager**, cree la carpeta `proveeduria` en `public_html` y súbale el ZIP.
3. Seleccione el ZIP y use **Extract**.
4. Mueva el contenido para que quede en `public_html/proveeduria/`.

### Opción B — FTP

Con FileZilla, suba el contenido a `public_html/proveeduria/`. Omitir `vendor/` si luego
ejecutará `composer install` por SSH.

### Opción C — SSH (recomendada)

```bash
ssh usuario@servidor
cd public_html
wget https://ruta/paquete.zip
unzip paquete.zip
mv proveeduria/* proveeduria/   # si el ZIP trae una carpeta superior
cd proveeduria
composer install --no-dev --optimize-autoloader
```

---

## 4. Configurar el document root

### Subdominio dedicado (recomendado)

En cPanel → **Domains → Subdomains**, cree `proveedrium.ejemplo.gob.mx` y en el campo
**Document Root** indique `public_html/proveeduria/public`.

### Dominio principal

En cPanel → **Domains → Domains**, edite el dominio y ponga el document root en
`public_html/proveeduria/public`. Con esta opción, los archivos quedan fuera del dominio y
conviene crear un `public_html/` con un `index.html` de redirección.

> **Importante:** el document root **debe** ser la carpeta `public/`. Si apunta a la raíz del
> proyecto, quedan expuestos `config/app.php` (con la contraseña de MySQL) y `storage/`.

---

## 5. Permisos

En **File Manager**, clic derecho → **Change Permissions**:

| Carpeta | Permiso |
|---|---|
| `config` | 775 |
| `storage` | 775 |
| `storage/logs` | 775 |
| `storage/uploads` | 775 |
| `storage/cache` | 775 |
| `storage/documents` | 775 |
| `storage/install.lock` (tras instalar) | 640 |

En **Select PHP Version**, elija la versión 8.2 o superior para el dominio.

Si los permisos siguen fallando, añada al `.htaccess` de `public/`:

```apache
<IfModule mod_php.c>
    php_value upload_max_filesize 8M
    php_value post_max_size 10M
    php_value memory_limit 256M
    php_value max_execution_time 120
</IfModule>
```

---

## 6. Instalar

Abra `https://proveeduria.ejemplo.gob.mx/install` y siga los cinco pasos.

En el paso 2 use los datos del punto 2. Si el servidor MySQL es local, el host es
`localhost` (no `127.0.0.1`, que en algunos hosting con vhosting no resuelve al socket).

Al terminar, el sistema queda bloqueado para nuevas instalaciones.

---

## 7. SSL

En cPanel → **SSL/TLS Status**, active **Let's Encrypt** para el subdominio y marque
**AutoSSL**. Después active el completado automático de HTTPS con las opciones de redirección
de **Force HTTPS Redirect**.

Una vez con HTTPS, las cookies de sesión viajan con la marca `Secure` automáticamente:
el sistema lo detecta en `$_SERVER['HTTPS']`.

---

## 8. Correo de notificaciones (opcional)

Si más adelante se activa el envío de correos, configure las cuentas SMTP en
**Configuración → Administración**. En cPanel los datos se obtienen en
**Email Accounts → Connect Devices** (host `mail.ejemplo.gob.mx`, puerto 465 con SSL o
587 con STARTTLS).

---

## 9. Respaldo programado

### 9.1 Desde el sistema

*Configuración → Sistema → Descargar respaldo* genera un `.sql` con la estructura y los datos
de las tablas del sistema. Es la vía recomendada: no requiere configuración de cron.

### 9.2 Con cron (respaldo automático)

En cPanel → **Cron Jobs**, añada una tarea diaria:

```bash
/usr/local/bin/php /home/USUARIO/public_html/proveeduria/tools/respaldo.php /home/USUARIO/respaldos
```

El script crea un archivo `.sql` con fecha, aplica una rotación (conserva los 30 respaldos más
recientes) y registra el resultado en `storage/logs/backup.log`.

Añada el envío del respaldo a un correo externo si la norma lo exige:

```bash
/usr/local/bin/php /home/USUARIO/public_html/proveeduria/tools/respaldo.php /home/USUARIO/respaldos && \
  cp /home/USUARIO/respaldos/$(ls -t /home/USUARIO/respaldos | head -1) /dev/null
```

> En cPanel, los cron se ejecutan con la configuración regional del servidor, normalmente
> `America/Mexico_City` para servidores mexicanos. Si el sistema y el cron usan zonas distintas,
> las fechas de los respaldos pueden no coincidir con las del sistema. Fije la zona horaria en
> *Configuración → Administración* de acuerdo con la del servidor.

---

## 10. Copias de seguridad del hosting

Active el **Almacenamiento de respaldo del servidor** de cPanel si el plan lo incluye, y
mantenga una copia fuera del servidor de los archivos de `config/` y de `storage/`.

---

## 11. Lista de verificación de publicación

- [ ] El document root apunta a `public/`.
- [ ] `config/app.php` no es accesible por HTTP (pruebe `https://dominio/config/app.php` → 404).
- [ ] `storage/` no es accesible por HTTP (pruebe `https://dominio/storage/logs/app-...log` → 404).
- [ ] El asistente `/install` está bloqueado y redirige a `/login`.
- [ ] PHP 8.2 o superior activo en el dominio.
- [ ] Extensiones `pdo_mysql`, `mbstring`, `dom`, `fileinfo` y `openssl` habilitadas.
- [ ] SSL activo y con redirección forzada.
- [ ] La verificación de integridad en *Configuración → Verificación de integridad* no reporta
      tablas faltantes ni migraciones pendientes.
- [ ] Se completó un flujo de prueba: proveedor → departamento → partida → orden → emisión →
      vale → PDF → cancelación.

---

## 12. Errores frecuentes en cPanel

| Síntoma | Causa | Solución |
|---|---|---|
| 404 en todas las rutas | El document root no es `public/` | Corrija el document root |
| 500 inmediato | PHP < 8.2 o extensión faltante | Revise *Select PHP Version* y los registros de errores |
| «No fue posible escribir la configuración» | Permisos de `config/` | 775 y propietario correcto |
| «No se encontró la plantilla del documento» | ZIP mal descomprimido | Vuelva a descomprimir y verifique `resources/document-templates/` |
| Los PDF salen sin el logotipo | `ext-gd` deshabilitada | Habilite `gd` |
| Se crea `config/app.php` con permisos 644 | Extractor del ZIP | `chmod 640 config/app.php` |
| El sistema pide el asistente otra vez | Se borró `storage/install.lock` | Restáurelo desde el respaldo |
