Saltar a contenido

jobs-deploy

Un solo contenedor con el panel de cron y alertas (panel-cron-alertas) y los 32 jobs migrados de los 18 repos job-*, listo para desplegar en la VM Linux. Python 3.11.

Estado: piloto en pilot/jobs-deploy/. Construido y levantado en Docker Desktop (Windows) el 2026-10-14: build OK, contenedor healthy, 32 jobs cargados y smoke en verde. Falta probar los jobs con secretos reales y desplegar en la VM; ver RUNBOOK.md.

Cómo está armado

 host (VM Linux)                        contenedor dabra-panel (python:3.11-slim, UID 10001)
 ┌───────────────────────┐              ┌────────────────────────────────────────────────────┐
 │ .env  (panel)         │──env_file──▶ │ /app            panel FastAPI + planificador       │
 │ secrets/<repo>.env    │──ro mount──▶ │ /run/secrets/dabra/<repo>.env                      │
 │ /var/lib/dabra        │──volume───▶  │ /var/lib/dabra/<job>/   datos (DABRA_DATA_DIR)     │
 │ /var/log/dabra        │──volume───▶  │ /data/logs/<job>/       logs de cada corrida       │
 │ volumen panel_data    │──volume───▶  │ /data/panel.db          base SQLite del panel      │
 └───────────────────────┘              │ /opt/dabra/jobs/<repo>/ código + .venv (en la imagen)│
                                        │   └─ .env ─▶ /run/secrets/dabra/<repo>.env         │
                                        └────────────────────────────────────────────────────┘
 panel ──(cron_expr)──▶ /opt/dabra/bin/dabra-job <repo> .venv/bin/python -m <paquete> [args]

Al arrancar, el entrypoint ejecuta python -m tools.sync_jobs --init: crea tablas y semilla, y da de alta o actualiza en el panel los 32 jobs leyendo cada job.yaml (el panel solo carga su semilla con la base vacía y no tiene API para crear jobs). Después lanza uvicorn con un único worker.

Carpetas

Ruta Qué es
Dockerfile, docker-compose.yml, .env.example Imagen, servicio panel, plantilla de configuración del panel
docker/ entrypoint.sh, dabra-job.sh (lanzador), smoke.sh (prueba de humo)
tools/ preparar_contexto.py, sync_jobs.py, generar_env_example.py, verificar_env.py
seed/ Semilla propia del panel: sin jobs de demo, reglas globales y reglas por job
secrets/ Un <repo>.env por job (no se versiona ni entra en la imagen)
certs/ CAs opcionales para el build tras un proxy/antivirus
tests/ Pruebas de sync_jobs (usan el esquema real del panel)
panel/, jobs/, MANIFEST.json Generados por preparar_contexto.py (en el repo real serán submódulos); no se versionan

Decisiones y por qué

Decisión Motivo
Imagen propia python:3.11-slim-bookworm con el código del panel copiado encima El proyecto fija 3.11 y la imagen del panel es 3.12. panel-cron-alertas no se modifica
Un venv por job, instalación editable Cada job calcula REPO_DIR desde su propio archivo para leer .env, sql/ y templates/; una instalación normal los dejaría en site-packages
uv con hardlinks para crear los 18 venvs Comparten pandas/numpy dentro de la capa; la imagen no se multiplica por 18
.env de cada job = enlace a /run/secrets/dabra/<repo>.env Los secretos no entran en la imagen y no chocan entre jobs (las 15 variables compartidas, como SMTP_* o TELEGRAM_TOKEN, pueden tener valores distintos por job)
Lanzador dabra-job entre el panel y el job Hace cd al repo (los comandos de job.yaml son relativos) y quita del entorno las variables del panel (SMTP_*, TELEGRAM_BOT_TOKEN...) que taparían las del job, porque los jobs cargan su .env sin pisar el entorno
ODBC Driver 17 y 18 Salesforce usa 17; el BYOD de ventas-online usa 18
wkhtmltopdf "patched Qt" desde GitHub El paquete de Debian no soporta las opciones de pdfkit. Solo amd64
sync_jobs refresca descripción/comando/rango/audit pero no cron/tolerancia/timeout/activo/ejecutar_interno Esos cinco se editan en el panel; --forzar los pisa
Los 32 jobs con ejecutar_interno: true: el panel es el único ejecutor El contenedor contiene los jobs y puede mudarse de una VM on premise a Azure; no depende de un cron del host. Los envíos a terceros se controlan con el traspaso job por job y con el rol operator para «Ejecutar ahora»
El importador falla sin tumbar el panel Un job.yaml roto no debe dejar sin alertas a los otros jobs; el error queda en docker compose logs

Jobs incluidos (32; 30 activos)

Job en el panel Repo Cron Activo Timeout (min)
proveedores_adidas envio-adidas 40 16 * * * si 20
envio_cambio_precios envio-cambio-precios 0 6 * * * si 30
proveedores_dass_fila envio-dass 0 17 * * * si 9
proveedores_dass_asics envio-dass 10 17 * * * si 9
proveedores_dass_umbro envio-dass 20 17 * * * si 9
envia_externo_txt_ventas_keengo envio-keengo 0 22 * * * si 20
envia_externo_txt_nike envio-nike 0 14 * * * si 30
onebeat_limpieza_sftp envio-onebeat 0 23 1 * * si 15
onebeat_mtsskus envio-onebeat 38 2 * * * si 30
onebeat_catalogo_atributos envio-onebeat 30 2 * * * si 30
onebeat_transactions envio-onebeat 42 2 * * * si 30
onebeat_stocklocations envio-onebeat 36 2 * * * si 30
onebeat_status envio-onebeat 51 2 * * * si 30
onebeat_given_target envio-onebeat 0 2 * * * si 15
envio_externo_excel_proveedores envio-proveedores-exceso 30 10 * * * si 60
envia_externo_txt_puma envio-puma 30 13 * * * si 30
envia_externo_txt_topper envio-topper 0 12 * * * si 20
dolarapi_minerva ingesta-dolarapi 0 19 * * * no 10
automatizacion_bajada_modo ingesta-modo 0 22 * * 1-5 si 20
salesforce_catalogo_v4 ingesta-salesforce-catalogo 0 8 * * * si 20
salesforce_catalogo_v5 ingesta-salesforce-catalogo 0 14 * * * si 20
adf_pipelines_monitor monitor-adf 0 7 * * * si 120
adf_monitor_ir_nodes monitor-adf 5 * * * * si 10
recibe_athenas_monitor monitor-athenas 20 8 * * * si 20
recibe_performance_analisis_pbi monitor-pbi-performance 30 21 * * 0,1,2,3,4 si 90
reporte_ejecutivo_ventas reporte-ejecutivo-ventas 15 8 * * * si 20
read_sharepoint_ventas_proyectadas reporte-ejecutivo-ventas 0 19 * * * si 15
reporte_venta_online_excel reporte-ventas-online 32 13,15,17,19,21 * * * si 20
reporte_venta_online_retailtrans reporte-ventas-online 37 13,15,17,19,21 * * * si 20
reporte_retail_dia_anterior reporte-ventas-online 58 7 * * * si 20
envia_ventas_telegram reporte-ventas-telegram 0 9 * * * si 10
envia_ventas_telegram_1150 reporte-ventas-telegram 50 11 * * * no 10

Cron, tolerancia y timeout son los del job.yaml; varios están marcados "propuesto" en cada repo y se ajustan desde el panel. Los dos inactivos (dolarapi_minerva, envia_ventas_telegram_1150) siguen el estado del job.yaml. Fuera del contenedor quedan los jobs en standby del catálogo (L14, L19, L22, W06, W08, W17, W23), que no tienen repo migrado.

Límites conocidos

  • Concurrencia: el panel ejecuta hasta 4 jobs a la vez (ThreadPoolExecutor(4)); el resto espera en cola. Hay franjas con muchos jobs juntos (Onebeat entre 02:00 y 02:51, ventas-online a las 13:32-13:37). Con pandas en varios jobs a la vez conviene revisar la memoria de la VM.
  • Zona horaria: TZ por defecto America/Argentina/Buenos_Aires (la del panel). Los cron y los jobs que usan hora local dependen de ella; confirmar que coincide con el servidor actual.
  • Shares de backup (PUMA_BACKUP_DIR, etc.): hay que montarlos en el contenedor (línea comentada en el compose). Sin montaje, los jobs dejan el zip en archive/.
  • Red: el contenedor sale por la red del host; hacen falta las reglas de salida hacia SQL Server, los SFTP de cada tercero, Microsoft Graph, Telegram, SMTP y la API de Anthropic.
  • Arquitectura: amd64 (el driver ODBC y wkhtmltopdf se instalan para esa plataforma).
  • Variables opcionales: verificar_env.py lista como faltante toda variable de variables_entorno sin valor, aunque el job tenga un valor por defecto.

Fuente: repositorio jobs-deploy, versión 5bbe011. Página generada con tools/publicar_docs.py.