Commit Graph
366 Commits
Author SHA1 Message Date
Lizandro Guarnizo 6807da8a2b fix: conectar app a red 'coolify' donde vive Redis de Coolify
El contenedor Redis (zqmfom0vw6nj3ae66mkwxek1) vive en la red 'coolify'.
La app estaba solo en la red nj05x5... → DNS SERVFAIL → health.php tardaba
10-12s intentando conectar → healthcheck timeout → unhealthy → 'no available server'.

Solución: declarar red coolify como external y conectar el servicio app.
Fix inmediato aplicado manualmente con: docker network connect coolify <container>
2026-03-12 16:58:44 -05:00
Lizandro Guarnizo a497dc4b31 fix: migración SQL + red Docker para Coolify
06_master_sync.sql:
- Comentario tenía ';' (La columna role_id ya existe; la FK) →
  el parser de migrate.php divide por ; y el texto 'la FK' quedaba
  como sentencia SQL → error SQLSTATE[42000]

docker-compose.yml:
- Eliminar whatsapp-network (red bridge propia)
- Con 1 solo servicio no se necesita red interna
- Coolify añade automáticamente su red nj05x5... (donde está Traefik)
- La red bridge extra podría interferir con el routing de Traefik
2026-03-12 16:42:14 -05:00
Lizandro Guarnizo 2537bc8cfc fix: healthcheck nunca retorna 503 — evita 'no available server'
health.php:
- DB fallo → 'warning' (no 'unhealthy', no cierra tráfico Traefik)
- Redis ya era warning desde commit anterior

docker-compose.yml:
- timeout: 5s → 10s (DB externa puede tardar más)
- start_period: 40s → 60s (tiempo suficiente para that migrations corran)
- fallback: si health.php falla, intenta / raíz antes de marcar unhealthy
2026-03-12 16:35:37 -05:00
Lizandro Guarnizo 3b85c4ac93 fix: docker-compose.yml limpiar volúmenes y container_name para Coolify
- Eliminar container_name (Coolify asigna su propio nombre, conflicto evitado)
- Eliminar ./:/var/www/html (bind mount sobreescribía código del contenedor en prod)
- Eliminar ./logs y ./uploads bind mounts (reemplazados por named volumes)
- Eliminar php-socket volume (ya no se usa)
- Usar named volumes app-logs/app-uploads (persistencia correcta en Coolify)
2026-03-12 16:32:46 -05:00
Lizandro Guarnizo 85fb463708 fix: 06_master_sync.sql corregir errores SQL para MariaDB
1. ADD CONSTRAINT IF NOT EXISTS no es estándar en MariaDB < 10.5 —
   eliminado el bloque FK de admin_users.role_id (la integridad la
   gestiona la aplicación).
2. AFTER `pdf_path` fallaba porque la columna no existe en lab_form_envios —
   eliminado el AFTER, la columna se agrega al final de la tabla.

Esto evita que la migración falle en cada deploy.
2026-03-12 16:30:03 -05:00
Lizandro Guarnizo ec2135442d fix: eliminar wait de Redis en entrypoint.sh
Redis es externo (Coolify managed) — esperar con redis-cli causaba
30 segundos de delay en cada arranque porque:
1. redis-cli no pasaba -a $REDIS_PASSWORD (auth fallaba)
2. Redis no es local, no tiene sentido hacer ping desde dentro del contenedor
La app conecta a Redis cuando necesita (RedisQueue, ConversationState, etc.)
2026-03-12 16:26:46 -05:00
Lizandro Guarnizo 9571b2677a fix: health.php Redis fallo no marca app como unhealthy
Redis es infraestructura opcional — si falla la conexión, retorna 'warning'
en lugar de 'unhealthy', evitando que Traefik muestre 'no available server'.
Solo DB down debe marcar el app como unhealthy (es crítico).
2026-03-12 16:22:43 -05:00
Lizandro Guarnizo 2a50a5e1d4 fix: crear .installation_completed (con punto) en Dockerfile
isInstallationCompleted() en config.php busca '.installation_completed' (con punto)
pero el Dockerfile solo creaba 'installation_completed' (sin punto).
Ahora se crean ambas variantes para cubrir todos los checks del código.
2026-03-12 16:09:23 -05:00
Lizandro Guarnizo 30e38720e2 fix: eliminar REDIS_HOST hardcodeado 'redis' en todos los archivos
- docker-compose.prod.yml: REDIS_HOST=redis → ${REDIS_HOST:-127.0.0.1}
  eliminados servicios redis/worker/maintenance (usan Coolify/Supervisor)
- .env, .env.docker: REDIS_HOST=redis → 127.0.0.1 (fallback seguro)
- .env.example: actualizado con comentario de Coolify
- health.php: fallback 'redis' → '127.0.0.1'
- PHP files (RedisQueue, ConversationState, etc.) ya usaban getenv() correctamente
2026-03-12 13:48:01 -05:00
Lizandro Guarnizo d50abb3ff3 fix: eliminar Redis y worker locales del docker-compose.yml
- Redis ahora es un Database Resource externo en Coolify
  Configurar: REDIS_HOST, REDIS_PORT, REDIS_PASSWORD en env vars
- Worker corre dentro del contenedor app via Supervisor (no servicio aparte)
- Eliminados: servicio redis, worker, redis-commander, volumenes db-data/redis-data
- Solo queda: servicio app + volumen php-socket
2026-03-12 13:44:41 -05:00
Lizandro Guarnizo c8a4a399fc fix: eliminar bloqueo infinito en espera de Redis al arrancar
- entrypoint.sh: Redis wait tenía loop infinito sin timeout → el contenedor
  se quedaba colgado para siempre si Redis tardaba, causando 504 Gateway Timeout
  Ahora tiene MAX_RETRIES=15 (30s) y continúa aunque Redis no esté disponible
- entrypoint.sh: removido set -e para que errores no-críticos (permisos,
  SSL, etc.) no maten el arranque del contenedor
- docker-compose.yml: removido depends_on redis con condition:service_healthy
  Docker bloqueaba el inicio de app hasta que Redis estuviera healthy,
  lo que podía exceder el timeout de Traefik
2026-03-12 13:31:57 -05:00
Lizandro Guarnizo 937a02e5ac debug: agregar try/catch y console.log en lab_usuarios.php para diagnosticar render 2026-03-12 13:24:41 -05:00
Lizandro Guarnizo 8a862e914a fix: crear installation_completed en build → activa modo producción PHP
Sin este archivo, config.php ejecuta con display_errors=1 (modo dev).
Los PHP warnings se inyectaban dentro del bloque <script> de las páginas,
rompiendo el JavaScript y causando que el contenido no se renderizara.

El archivo se crea en el RUN del Dockerfile así sobrevive cada deploy.
2026-03-12 10:40:37 -05:00
Lizandro Guarnizo 81bdda2ca3 feat(migrate): agregar migración de datos seed para roles y módulos
20260304_roles_seed_data.sql — inicializa datos en roles/role_modules
y vincula admin_users.role_id. Todos los statements son idempotentes
(UPDATE + INSERT IGNORE), por lo que se pueden re-ejecutar sin problemas.

Esto asegura que en cualquier deploy los módulos de rol y los colores
estén correctos, aunque la migración DDL ya haya sido registrada.
2026-03-12 10:24:52 -05:00
Lizandro Guarnizo 33dfc0cf71 fix(migrate): detectar tablas faltantes aunque migración esté registrada
Si una migración está en la tabla migrations pero la tabla que crea ya
no existe en la BD (ej. Coolify recreó la DB), el sistema la re-ejecuta
automáticamente. Esto evita el error anterior donde 10 lab migrations
estaban registradas como ejecutadas pero las tablas no existían.
2026-03-12 09:46:07 -05:00
Lizandro Guarnizo 01ea867229 fix: usar expose en lugar de ports en docker-compose.yml para Coolify/Traefik
El archivo docker-compose.yml es el que usa Coolify por defecto.
Con 'ports: 8080:80' Traefik no sabía a qué puerto rutear en cada
redeploy. Con 'expose: 80' Traefik detecta el puerto 80 del contenedor
directamente (igual que docker-compose.prod.yml).

Para desarrollo local usar: docker-compose -f docker-compose.dev.yml up
2026-03-12 09:36:27 -05:00
Lizandro Guarnizo 7000464d36 fix(migrate): robustecer parser SQL y no registrar migración si hubo errores
- Eliminar comentarios de bloque /* */ antes de parsear
- Limpiar líneas vacías y comentarios -- sentencia por sentencia
- Agregar 'Duplicate key name' y 'Multiple primary key defined' a errores ignorables
- Solo registrar en tabla migrations si no hubo errores reales
- Si una sentencia falla, continuar con las demás pero marcar had_error=true
2026-03-12 09:27:46 -05:00
Lizandro Guarnizo 28307f44d1 fix: remove labels from compose (conflicts with Coolify), EXPOSE only port 80 2026-03-11 22:38:36 -05:00
Lizandro Guarnizo 0b3b499c3f fix: migrate.php also scans migrations/ folder for lab SQL files 2026-03-11 22:29:00 -05:00
Lizandro Guarnizo ef6c4277a6 fix: add explicit Traefik loadbalancer port label (port 80) 2026-03-11 22:01:58 -05:00
Lizandro Guarnizo 7586954e53 fix: Predis ping() returns Status object, cast to string before compare 2026-03-11 21:41:58 -05:00
Lizandro Guarnizo 7cca8342b5 refactor: unify env vars — no hardcoded credentials, LOG_LEVEL/SESSION from env 2026-03-11 21:16:52 -05:00
Lizandro Guarnizo 7769e5d4f0 Update .env 2026-03-11 20:53:44 -05:00
Lizandro Guarnizo 6e03169c39 feat: remove mysql service from compose, use external Coolify DB resource 2026-03-11 20:31:11 -05:00
Lizandro Guarnizo 1b9942442a fix: disable MariaDB SSL for internal Docker networking + worker MySQL readiness wait 2026-03-11 20:22:19 -05:00
Lizandro Guarnizo 06e4ad6fd5 fix: regenerate vendor/ if Coolify mounts empty volume over /var/www/html 2026-03-10 23:05:02 -05:00
Lizandro Guarnizo b045d9db3a fix: use named volumes, reduce nginx connections to 1024, 1 worker process 2026-03-10 22:47:42 -05:00
Lizandro Guarnizo 7a17fefb3e fix: pin redis extension version 6.0.2 for reproducible builds 2026-03-10 22:39:33 -05:00
Lizandro Guarnizo 9080444daa fix: remove port bindings for Coolify Traefik proxy 2026-03-10 22:29:32 -05:00
Lizandro Guarnizo 1fb4361f96 fix: worker logs permission denied + migration AFTER password 2026-03-10 22:23:30 -05:00
Lizandro Guarnizo db469b2134 up 2026-03-10 18:42:51 -05:00
Lizandro Guarnizo b57fc16ab3 fix: archivos >200KB usan URL publica, evita uploadMedia() con OpenSSL 3.x
El contenedor falla al subir a Facebook archivos >~200KB por renegociacion
TLS de OpenSSL 3.x (errno 55). Solucion sin rebuild:
- Archivos <=200KB: uploadMedia() como antes (funciona OK)
- Archivos >200KB: enviar URL publica - WhatsApp descarga desde el servidor
  directamente, sin pasar por el contenedor ni por OpenSSL

Aplica a imagenes, documentos, videos y audios.
2026-02-21 12:30:56 -05:00
Lizandro Guarnizo edcefbe67c fix: comprimir imagen pegada hasta <250KB con calidad progresiva
OpenSSL 3.x en contenedor hace renegociacion TLS con Facebook >~300KB
causando errno 55. Forzar imagen a quedar bajo 250KB:
- Escalar a max 1920px si es más grande
- Intentar JPEG q=0.85, 0.70, 0.55, 0.40, 0.25 hasta pasar el umbral
- JPEG/WebP ya bajo 250KB se pasan sin modificar
2026-02-21 12:26:36 -05:00
Lizandro Guarnizo dd6dd2e1f4 fix: comprimir imagen pegada a JPEG antes de subir a WhatsApp
Imagen PNG del portapapeles puede ser 1-5MB sin comprimir.
Facebook resetea TCP (errno 55) al recibir payloads grandes desde el
contenedor con OpenSSL 3.x. Solución: convertir PNG→JPEG 0.85 vía Canvas
en el navegador antes de subir → reduce tamaño ~10x → upload exitoso.
JPEG/WebP ya comprimidos se pasan sin modificar.
2026-02-21 12:20:02 -05:00
Lizandro Guarnizo a716cd187a Update WhatsAppService.php 2026-02-21 12:02:15 -05:00
Lizandro Guarnizo 51f1b04293 up 2026-02-21 11:45:32 -05:00
Lizandro Guarnizo e00c96c614 Update WhatsAppService.php 2026-02-21 11:39:25 -05:00
Lizandro Guarnizo 0aa450be67 up 2026-02-21 11:33:56 -05:00
Lizandro Guarnizo 5dd48ba5c2 up 2026-02-21 11:24:15 -05:00
Lizandro Guarnizo 26afa7f36b Update MediaService.php 2026-02-21 11:03:03 -05:00
Lizandro Guarnizo 36a1b556c3 Update MediaService.php 2026-02-21 10:53:27 -05:00
Lizandro Guarnizo a3e089caab up 2026-02-21 10:49:39 -05:00
Lizandro Guarnizo 72e7f8c242 Update php-fpm.conf 2026-02-21 10:25:53 -05:00
Lizandro Guarnizo 237f4aea0f Update webhook.php 2026-02-21 10:19:10 -05:00
Lizandro Guarnizo 6bab34bf13 up 2026-02-21 10:14:14 -05:00
Lizandro Guarnizo f05d4a20cb Update MediaService.php 2026-02-21 09:43:28 -05:00
Lizandro Guarnizo 1c2bc3eac3 Update MediaService.php 2026-02-21 09:41:07 -05:00
Lizandro Guarnizo 349dcff45e Update MediaService.php 2026-02-21 09:32:03 -05:00
Lizandro Guarnizo 1bd7588e86 up 2026-02-21 09:29:27 -05:00
Lizandro Guarnizo 07333be7ce Update MediaService.php 2026-02-21 09:27:09 -05:00