Files
whatsapp/docker/entrypoint.sh
T
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

159 lines
6.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Entrypoint script para el contenedor
# set -e removido: comandos no críticos (permisos, SSL) no deben matar el arranque
echo "🚀 Iniciando WhatsApp Bot Manager..."
# Esperar a que Redis esté disponible (con timeout para no bloquear el arranque)
if [ "${REDIS_HOST:-redis}" != "" ]; then
echo "⏳ Esperando Redis..."
MAX_RETRIES=15
RETRY=0
until redis-cli -h ${REDIS_HOST:-redis} -p ${REDIS_PORT:-6379} ping 2>/dev/null | grep -q PONG; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRIES ]; then
echo "⚠️ Redis no disponible después de $MAX_RETRIES intentos, continuando sin Redis..."
break
fi
echo " Redis no disponible, intento $RETRY/$MAX_RETRIES..."
sleep 2
done
if [ $RETRY -lt $MAX_RETRIES ]; then
echo "✅ Redis conectado"
fi
fi
# Esperar a que MySQL esté disponible
if [ "${DB_HOST}" = "mysql" ] || [ "${DB_HOST}" = "db" ]; then
echo "⏳ Esperando MySQL local..."
MAX_RETRIES=30
RETRY=0
until mariadb -h "${DB_HOST:-mysql}" -u "${DB_USER:-whatsapp_user}" -p"${DB_PASS}" --skip-ssl -e "SELECT 1" >/dev/null 2>&1; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRIES ]; then
echo "⚠️ MySQL no disponible después de $MAX_RETRIES intentos, continuando..."
break
fi
echo " MySQL no disponible, intento $RETRY/$MAX_RETRIES..."
sleep 2
done
if [ $RETRY -lt $MAX_RETRIES ]; then
echo "✅ MySQL conectado"
fi
elif [ "${DB_HOST}" != "localhost" ] && [ "${DB_HOST}" != "127.0.0.1" ]; then
echo "️ Usando base de datos externa (${DB_HOST}), omitiendo verificación de conectividad..."
fi
# Crear directorios si no existen
mkdir -p /var/www/html/logs
mkdir -p /var/www/html/uploads
mkdir -p /var/cache/nginx
mkdir -p /run/php
mkdir -p /var/lib/nginx/tmp/client_body
mkdir -p /var/lib/nginx/tmp/proxy
mkdir -p /var/lib/nginx/tmp/fastcgi
mkdir -p /var/lib/nginx/tmp/uwsgi
mkdir -p /var/lib/nginx/tmp/scgi
# Establecer permisos ANTES de iniciar servicios
chown -R www:www /var/www/html/logs
chown -R www:www /var/www/html/uploads
chmod -R 775 /var/www/html/logs
chmod -R 775 /var/www/html/uploads
# IMPORTANTE: nginx necesita acceso a sus directorios temporales
# Usar grupo nginx para compartir acceso entre nginx y www
chown -R nginx:nginx /var/lib/nginx
chmod -R 775 /var/lib/nginx/tmp
# Generar certificados SSL si no existen
SSL_DIR="/etc/nginx/ssl"
if [ ! -f "$SSL_DIR/server.crt" ] || [ ! -f "$SSL_DIR/server.key" ]; then
echo "🔐 Generando certificados SSL autofirmados..."
mkdir -p "$SSL_DIR"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "$SSL_DIR/server.key" \
-out "$SSL_DIR/server.crt" \
-subj "/C=CO/ST=Cundinamarca/L=Bogota/O=U-Site/OU=WhatsApp Bot/CN=bot.u-s.app" \
-addext "subjectAltName=DNS:bot.u-s.app,DNS:localhost,DNS:*.u-s.app,IP:127.0.0.1" 2>/dev/null || \
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "$SSL_DIR/server.key" \
-out "$SSL_DIR/server.crt" \
-subj "/C=CO/ST=Cundinamarca/L=Bogota/O=U-Site/OU=WhatsApp Bot/CN=bot.u-s.app"
chmod 600 "$SSL_DIR/server.key"
chmod 644 "$SSL_DIR/server.crt"
echo "✅ Certificados SSL generados para bot.u-s.app"
else
echo "✅ Certificados SSL existentes encontrados"
fi
# Ejecutar migraciones de BD (si existen)
if [ -f /var/www/html/database/migrate.php ]; then
echo "🔄 Ejecutando migraciones..."
php /var/www/html/database/migrate.php || echo "⚠️ Migraciones fallaron o no aplicables"
fi
# Generar archivo .env desde variables de entorno (si no existe)
if [ ! -f /var/www/html/.env ]; then
echo "📝 Generando .env desde variables de entorno..."
cat > /var/www/html/.env <<EOF
# Generado automáticamente por Docker
DB_HOST=${DB_HOST:-db}
DB_PORT=${DB_PORT:-3306}
DB_NAME=${DB_NAME:-whatsapp_bot}
DB_USER=${DB_USER:-whatsapp_user}
DB_PASS=${DB_PASS}
REDIS_HOST=${REDIS_HOST:-redis}
REDIS_PORT=${REDIS_PORT:-6379}
REDIS_PASSWORD=${REDIS_PASSWORD:-}
REDIS_DB=0
WHATSAPP_TOKEN=${WHATSAPP_TOKEN}
WHATSAPP_PHONE_NUMBER_ID=${WHATSAPP_PHONE_NUMBER_ID}
WEBHOOK_VERIFY_TOKEN=${WEBHOOK_VERIFY_TOKEN}
LOG_LEVEL=${LOG_LEVEL:-INFO}
ENABLE_RATE_LIMIT=${ENABLE_RATE_LIMIT:-true}
EOF
chown www:www /var/www/html/.env
fi
# Verificar vendor/ — Coolify puede montar un volumen vacío sobre /var/www/html
# Si vendor/autoload.php no existe, regenerar dependencias
if [ ! -f /var/www/html/vendor/autoload.php ]; then
echo "⚠️ vendor/autoload.php no encontrado (volumen vacío de Coolify). Ejecutando composer install..."
cd /var/www/html && composer install --no-dev --optimize-autoloader --no-interaction 2>&1
echo "✅ Dependencias instaladas"
else
echo "✅ vendor/autoload.php presente"
fi
# Limpiar cache de OPcache
if [ -f /usr/local/bin/php ]; then
echo "🧹 Limpiando cache de OPcache..."
php -r "if(function_exists('opcache_reset')) opcache_reset();"
fi
# Configurar crontab para tareas programadas (usar /etc/crontabs/root para que crond lo ejecute como root)
echo "⏰ Configurando cron jobs..."
cat > /etc/crontabs/root <<EOF
# Procesar mensajes delayed cada minuto
* * * * * cd /var/www/html && /usr/local/bin/php -r "require 'vendor/autoload.php'; use WhatsApp\Queue\RedisQueue; \$q = new RedisQueue(); \$q->processDelayed('messages'); \$q->processDelayed('media');" >> /tmp/delayed_processor.log 2>&1
# Procesar cola de media pendiente cada 2 minutos
*/2 * * * * cd /var/www/html && /usr/local/bin/php scripts/media_worker.php >> /tmp/media_worker.log 2>&1
# Limpiar logs antiguos (diario a las 3 AM)
0 3 * * * cd /var/www/html && /usr/local/bin/php -r "require 'classes/LoggerFactory.php'; echo LoggerFactory::cleanup(30) . ' logs eliminados';" >> /tmp/log_cleanup.log 2>&1
# Health check de workers (cada 5 minutos)
*/5 * * * * supervisorctl status whatsapp-worker:* | grep -q RUNNING || supervisorctl restart whatsapp-worker:* >> /tmp/worker_monitor.log 2>&1
EOF
echo "✅ Configuración completada"
echo "🎯 Iniciando servicios..."
# Ejecutar comando pasado al contenedor
exec "$@"