Tareas Celery

NoxPanel usa Celery 5.3+ con Redis como broker y DatabaseScheduler de django-celery-beat para programar tareas periódicas. Las tareas se definen en ficheros tasks.py de cada módulo.

Configuración

# proxmoxpanel/settings.py
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://redis:6379/0')
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

Servicios Docker:

  • celery_worker: Ejecuta las tareas (concurrency=4)

  • celery_beat: Programa y despacha tareas periódicas

Tareas por Módulo

Billing

Ubicación: billing/tasks.py

Tarea

Descripción

Frecuencia

billing.track_vm_usage_hourly

Registra uso horario para suscripciones VM activas con facturación por hora

Cada hora

billing.track_hosting_usage_daily

Registra uso diario para suscripciones de hosting

Cada 24h

billing.generate_monthly_invoices

Genera facturas mensuales para todos los tenants con suscripciones activas. Ejecuta verificación diaria, genera factura del mes anterior

Cada 24h

billing.check_overdue_invoices

Marca facturas pendientes como vencidas y envía emails de recordatorio (dunning). También envía notificaciones Telegram

Cada hora

billing.renew_expiring_subscriptions

Renueva suscripciones cuyo periodo ha finalizado. Avanza fechas al siguiente periodo y genera facturas de renovación. Excluye suscripciones Stripe/PayPal (gestionadas via webhooks)

Cada hora

Hosting

Ubicación: hosting/tasks.py

Tarea

Descripción

Frecuencia

hosting.sync_hosting_quotas

Sincroniza el uso real de cuotas por tenant: sitios, bases de datos, dominios, FTP, buzones, alias y shell users. Alerta cuando se superan cuotas

Cada hora

hosting.verify_dns_records

Verifica registros DNS críticos (A root, MX, SPF) para todas las zonas activas. Registra warnings para DNS mal configurado

Cada hora

hosting.check_ssl_expiry

Verifica fechas de expiración de certificados SSL. Alerta si expiran en <30 días. Intenta renovación automática para Let’s Encrypt

Cada 24h

hosting.sync_mail_cert

Registra estado de despliegue de certificados SNI para mail. El sync real lo ejecuta sync_sni_certs.sh via cron del host

Cada 6h

hosting.sync_ssl_certificates

Sincroniza certificados SSL desde acme.json de Traefik a la base de datos Django (modelo HostingSSLCertificate)

Cada 6h

hosting.auto_backup_sites

Backup nocturno automatizado de todos los sitios activos. Genera tarballs con archivos + dumps de BD

Cada 24h (nocturno)

hosting.cleanup_old_backups

Elimina backups automáticos con más de 30 días. Preserva backups manuales y limpia registros de backups fallidos

Cada 24h

hosting.cleanup_orphan_records

Detecta registros huérfanos (existen en DB pero no en hosting engine) y los marca como inactivos

Solo manual

Ticketing

Ubicación: ticketing/tasks.py

Tarea

Descripción

Frecuencia

ticketing.fetch_emails

Recupera emails de todas las cuentas de correo activas y los convierte en tickets. Soporta IMAP y OAuth2 (Microsoft/Google)

Cada 5 min

ticketing.check_sla_breaches

Detecta y escala tickets con violaciones SLA. Incumplimiento de primera respuesta: asigna al manager del departamento. Incumplimiento de resolución: escala prioridad a “urgente” y notifica admins

Cada 15 min

ticketing.send_ticket_notification

Envía emails de notificación para eventos: new_ticket, new_reply, status_changed, sla_breach. Enruta a destinatarios apropiados

Bajo demanda (.delay())

ticketing.auto_close_resolved

Cierra automáticamente tickets resueltos hace >7 días. Actualiza estado a “closed” y registra timestamp

Cada 24h

Notifications

Ubicación: notifications/tasks.py

Tarea

Descripción

Frecuencia

notifications.send_notification_email

Envía email para una notificación específica. Compone asunto + cuerpo con título, mensaje y URL. Marca como email_sent

Bajo demanda

notifications.cleanup_old_notifications

Elimina notificaciones leídas con más de 90 días. Las no leídas se preservan independientemente de la antigüedad

Solo manual

VMs (Threading, no Celery)

Ubicación: vms/tasks.py

Note

Las tareas de VMs usan threading (no Celery @shared_task) para comunicación en tiempo real via WebSocket durante la creación/eliminación de VMs.

  • create_vm_async() — Creación de VM con progreso via WebSocket

  • delete_vm_async() — Eliminación de VM con progreso

  • clone_vm_async() — Clonación de VM

  • migrate_vm_async() — Migración de VM entre nodos

Resumen de Programación

Tarea

Frecuencia

Módulo

Criticidad

ticketing.fetch_emails

5 min

Ticketing

Alta

ticketing.check_sla_breaches

15 min

Ticketing

Alta

billing.track_vm_usage_hourly

1 hora

Billing

Alta

billing.check_overdue_invoices

1 hora

Billing

Alta

billing.renew_expiring_subscriptions

1 hora

Billing

Alta

hosting.sync_hosting_quotas

1 hora

Hosting

Media

hosting.verify_dns_records

1 hora

Hosting

Media

hosting.sync_mail_cert

6 horas

Hosting

Media

hosting.sync_ssl_certificates

6 horas

Hosting

Baja

billing.track_hosting_usage_daily

24 horas

Billing

Alta

billing.generate_monthly_invoices

24 horas

Billing

Alta

hosting.check_ssl_expiry

24 horas

Hosting

Media

hosting.auto_backup_sites

24 horas

Hosting

Alta

hosting.cleanup_old_backups

24 horas

Hosting

Baja

ticketing.auto_close_resolved

24 horas

Ticketing

Baja

Comandos Útiles

# Ver logs del worker
docker logs noxpanel-celery_worker-1 --tail 100

# Ver logs del beat (scheduler)
docker logs noxpanel-celery_beat-1 --tail 100

# Ejecutar tarea manualmente
docker exec noxpanel-web-1 python manage.py shell -c \
    "from billing.tasks import check_overdue_invoices; \
     check_overdue_invoices.delay()"

# Ver tareas programadas (via Django admin)
# /admin/django_celery_beat/periodictask/

# Reiniciar worker y beat
docker restart noxpanel-celery_worker-1 noxpanel-celery_beat-1

Troubleshooting

Las tareas no se ejecutan:

  1. Verificar que Redis está corriendo: docker logs noxpanel-redis-1

  2. Verificar que el worker está sano: docker ps | grep celery

  3. Verificar conexión del worker: docker logs noxpanel-celery_worker-1 | head -20

Las tareas periódicas no se disparan:

  1. Verificar que celery_beat está corriendo y sano

  2. Verificar que DatabaseScheduler se configuró correctamente

  3. Comprobar las tareas en Django admin: /admin/django_celery_beat/periodictask/

Error de importación en tarea:

Las tareas se registran con nombres explícitos (name='module.task_name'). Si cambia el nombre del módulo, actualizar el CELERY_BEAT_SCHEDULE y los registros en django_celery_beat.