> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Despliegue de Reporter

> Despliega Reporter: un binario con selector de modo de ejecución, MongoDB, la cola de comandos de informe, almacenamiento de objetos compatible con S3, Redis o Valkey, dimensionamiento del worker y retención de informes con una política de ciclo de vida del bucket.

Reporter se entrega como un único binario con dos superficies. `RUN_MODE` selecciona qué superficies sirve un proceso, así que la misma imagen corre como la API, como el worker de informes, o como ambos. Detrás de ellas hay cuatro dependencias.

Reporter lee tus bases de datos mediante un motor de extracción que corre dentro del proceso worker. No hay un servicio de extracción aparte que desplegar.

## Lo que despliegas

***

| Componente                    | Rol                                                                                       | Escala según                       |
| ----------------------------- | ----------------------------------------------------------------------------------------- | ---------------------------------- |
| **Superficie de API**         | API REST de plantillas, informes, plazos y fuentes de datos. Publica comandos de informe. | Tasa de peticiones.                |
| **Worker de informes**        | Consumidor de cola. Extrae los datos, renderiza el informe y escribe el artefacto.        | Profundidad de la cola.            |
| **MongoDB**                   | Plantillas, informes, plazos y el outbox durable de eventos.                              | Volumen de metadatos.              |
| **RabbitMQ**                  | La cola de comandos de informe, y el exchange de eventos de negocio.                      | Tasa de informes.                  |
| **Almacenamiento de objetos** | Fuentes de plantilla e informes renderizados. Compatible con S3.                          | Volumen de artefactos y retención. |
| **Redis o Valkey**            | Bloqueos de idempotencia, caché de esquemas y ciclo de vida de tenants.                   | Ambas superficies.                 |

## Modos de ejecución

***

`RUN_MODE=api` sirve todas las operaciones REST, más `/health`, `/readyz` y `/version`, en la dirección de `SERVER_ADDRESS`. `RUN_MODE=worker` consume la cola de comandos de informe y sirve `/health` y `/readyz` en `HEALTH_PORT`. `RUN_MODE=all` corre las dos superficies en un solo proceso.

Usa `all` para desarrollo local. En producción, despliega las dos superficies por separado, para que la generación de informes escale por su cuenta.

```bash theme={null}
# Despliegue de API
RUN_MODE=api
SERVER_ADDRESS=:4005

# Despliegue de worker
RUN_MODE=worker
HEALTH_PORT=4006
```

## MongoDB

***

Las dos superficies usan el mismo despliegue de MongoDB. La superficie de API escribe plantillas, informes y plazos; el worker actualiza un informe a medida que lo completa.

En modo single-tenant, `MONGO_HOST` y `MONGO_NAME` son obligatorias en el arranque. En modo multi-tenant, cada tenant recibe su propia base de datos, resuelta a partir del JWT de la petición. Ese camino falla cerrado: una petición que lleva un tenant sin base de datos de tenant devuelve un error en lugar de tocar una base de datos compartida.

## RabbitMQ

***

Dos asuntos distintos comparten un mismo broker.

### La cola de comandos de informe

Esta cola lleva el trabajo desde la superficie de API hasta el worker. `RABBITMQ_EXCHANGE`, `RABBITMQ_GENERATE_REPORT_QUEUE` y `RABBITMQ_GENERATE_REPORT_KEY` nombran el exchange, la cola y la routing key. La superficie de API publica, así que necesita las tres. El worker solo consume, así que necesita `RABBITMQ_GENERATE_REPORT_QUEUE` sola. Las dos superficies necesitan la conexión al broker en sí, y los objetos deben existir antes de que arranquen los servicios.

El canal es interno de Reporter. Para saber que un informe terminó, suscríbete a los eventos de negocio de abajo, o consulta el informe.

Un worker que falla un mensaje lo reintenta hasta cinco veces con backoff, y después lo rechaza sin volver a encolarlo. Liga un dead-letter exchange a la cola de comandos, para que un informe rechazado caiga en un lugar que puedas inspeccionar.

### El exchange de eventos

Los eventos de negocio (`template.*`, `report.*`, `deadline.*`) van a un exchange que nombras en `RABBITMQ_REPORT_EVENTS_EXCHANGE`. El valor lo define el operador; `reporter.events` es el valor de referencia.

Define ese exchange, `STREAMING_BROKERS` y `STREAMING_CLOUDEVENTS_SOURCE` siempre que `STREAMING_ENABLED=true`. Con el streaming apagado, las dos superficies arrancan con normalidad y no publican nada.

## Almacenamiento de objetos

***

Reporter usa un único bucket compatible con S3, nombrado en `OBJECT_STORAGE_BUCKET`. Contiene dos clases de objeto, cada una bajo su propio prefijo:

* la fuente de la plantilla, como `templates/<templateId>.tpl`
* el informe renderizado, como `reports/<templateId>/<reportId>.<format>`

En modo multi-tenant, los dos prefijos quedan bajo el tenant dueño del objeto: `<tenantId>/templates/...` y `<tenantId>/reports/...`.

AWS S3, MinIO y SeaweedFS funcionan. Alcanza SeaweedFS por su gateway S3. `OBJECT_STORAGE_USE_PATH_STYLE=true` es lo que esperan MinIO y SeaweedFS, y `OBJECT_STORAGE_DISABLE_SSL` se queda en `false` fuera del desarrollo local.

### Retención de informes

Reporter conserva cada informe que renderiza, así que el bucket crece con tu volumen de informes. Define la expiración en el bucket, con la política de ciclo de vida del propio almacén de objetos, sobre la ventana que exigen tus reglas de retención.

<Warning>
  **Ancla la regla en el prefijo de informes que produce tu modo de tenancy.** En modo single-tenant, cada clave de informe empieza en `reports/`, así que una regla sobre ese prefijo cubre el bucket. En modo multi-tenant, la clave lleva el tenant por delante, así que la regla necesita el prefijo completo `<tenantId>/reports/`, una regla por tenant. Deja `templates/` fuera de alcance en los dos casos: una regla que cubre el bucket entero también borra las plantillas desde las que se renderizan tus informes.
</Warning>

## Redis o Valkey

***

`REDIS_HOST` es obligatoria en la superficie de API. En el worker solo es obligatoria cuando `MULTI_TENANT_ENABLED=true`, donde cachea el descubrimiento de tenants. Redis respalda el bloqueo de idempotencia en la creación de informes, la caché de esquemas de fuentes de datos y los mensajes de ciclo de vida de tenants en modo multi-tenant.

El estado de idempotencia vive en Redis, no en la memoria del proceso, así que las réplicas de API lo comparten. La misma petición de informe enviada dos veces, a dos réplicas, crea un solo informe.

## Fuentes de datos

***

Reporter lee los datos de los informes desde fuentes de datos PostgreSQL y MongoDB declaradas en el entorno, un bloque `DATASOURCE_{NAME}_*` por fuente. Consulta [Variables de entorno](/es/reporter/reporter-environment-variables) para ver el bloque.

No hay una API que registre una fuente de datos, así que una fuente nueva es un cambio de configuración y un reinicio. Reporter también arranca sin ninguna configurada, y sirve plantillas, plazos y métricas.

## Dimensionar el worker

***

`RABBITMQ_NUMBERS_OF_WORKERS` define cuántos trabajos de informe corre en paralelo un proceso worker. Para escalar horizontalmente, agrega réplicas del worker y guíalas por la profundidad de la cola de comandos.

La salida en PDF se renderiza con un pool de navegador headless: `PDF_POOL_WORKERS` renderizados concurrentes, con valor por defecto 2, cada uno acotado por `PDF_TIMEOUT_SECONDS`, con valor por defecto 90. Dimensiona la memoria del worker contra ese pool, y no solo contra las filas que lee un informe. Los demás formatos de salida no lo usan.

Cada informe lleva además límites fijos de extracción. Son 10 fuentes de datos, 50 tablas por fuente de datos y 200 campos por tabla, con 4 fuentes de datos leídas a la vez, un plazo de 300 segundos y un tope de 100 MiB de datos extraídos. Las variables `ENGINE_*` los cambian.

## Modo de despliegue y TLS

***

`DEPLOYMENT_MODE` declara el sabor del despliegue: `local`, `byoc` o `saas`. Etiqueta la respuesta de `/readyz` y, en `saas`, exige TLS.

<Warning>
  **El modo SaaS exige TLS en todas las dependencias.** Define `DEPLOYMENT_MODE=saas` y una URL en texto plano de MongoDB, RabbitMQ, Redis, almacenamiento de objetos o Tenant Manager detiene el proceso. Se detiene antes de que se abra cualquier conexión.
</Warning>

Deja `ALLOW_INSECURE_TLS` sin definir en producción. Omite esas verificaciones, y el stack de desarrollo local es el único lugar para ella.

## Verificaciones de arranque

***

Reporter valida su configuración antes de servir nada. Cada verificación de abajo detiene el proceso, y el error nombra todas las variables en falta.

| Disparador                                                                                                                                                                   | Lo que ve el operador                                                                 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `SERVER_ADDRESS`, `REDIS_HOST` o cualquiera de las tres variables de la cola de comandos ausente en la superficie de API                                                     | La validación de configuración falla y lista cada variable ausente.                   |
| `RABBITMQ_GENERATE_REPORT_QUEUE` ausente en la superficie de worker                                                                                                          | La validación de configuración falla y la nombra.                                     |
| `MONGO_HOST` o `MONGO_NAME` ausente, en modo single-tenant                                                                                                                   | La validación de configuración las nombra.                                            |
| `MULTI_TENANT_ENABLED=true` sin `MULTI_TENANT_URL` o `MULTI_TENANT_SERVICE_API_KEY`                                                                                          | La validación de configuración nombra la variable que necesita el runtime de tenants. |
| `STREAMING_ENABLED=true` sin `RABBITMQ_REPORT_EVENTS_EXCHANGE`, `STREAMING_BROKERS` y `STREAMING_CLOUDEVENTS_SOURCE` — las tres son obligatorias para arrancar con streaming | El arranque aborta en lugar de correr con eventos que no van a ninguna parte.         |
| `DEPLOYMENT_MODE=saas` con una URL de dependencia en texto plano                                                                                                             | El arranque aborta antes de que se abra cualquier conexión.                           |

<Note>
  **Una dependencia caída en el arranque no produce un pod roto en silencio.** `/health` devuelve 503 hasta que la autosonda de arranque tiene éxito. El kubelet entonces reinicia el pod en lugar de enviarle tráfico.
</Note>

## Actualizaciones progresivas

***

Ante `SIGTERM`, las dos superficies entran en drenaje. `/readyz` responde 503 desde el momento en que llega la señal, antes de que los servidores empiecen a cerrarse, y las peticiones y los mensajes en vuelo terminan. Kubernetes saca el pod de los endpoints del Service mientras este todavía funciona.

Define tu periodo de gracia de terminación por encima de tu renderizado de informe más largo. Consulta la [referencia de salud y readiness](/es/reference/health-and-readiness) para ver qué reportan las sondas durante un drenaje.

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Variables de entorno" icon="gear" href="/es/reporter/reporter-environment-variables">
    Todas las variables de Reporter, por categoría.
  </Card>

  <Card title="Configuración BYOC" icon="sliders" href="/es/reference/byoc-configuration">
    Los bloques de configuración que comparte cada producto de Lerian.
  </Card>

  <Card title="Salud y readiness" icon="heart-pulse" href="/es/reference/health-and-readiness">
    El contrato de sondas y qué significa cada respuesta.
  </Card>

  <Card title="Conectar Reporter a Midaz" icon="link" href="/es/reporter/connecting-reporter-to-midaz">
    Apunta Reporter a una base de datos de Midaz y renderiza tu primer informe.
  </Card>
</CardGroup>
