> ## 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 un selector de modo de ejecución, MongoDB, la cola de comandos de informes, almacenamiento de objetos compatible con S3, Redis o Valkey, el dimensionamiento del worker y la retención de informes mediante una política de ciclo de vida del bucket.

Reporter se distribuye como un solo binario con dos superficies, y `RUN_MODE` selecciona qué superficies sirve un proceso. La misma imagen se ejecuta como la API, como el worker de informes o como ambas. Detrás de ellas hay cuatro dependencias.

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

## Qué despliegas

***

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

## Modos de ejecución

***

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

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

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

# Worker deployment
RUN_MODE=worker
HEALTH_PORT=4006
```

## MongoDB

***

Ambas superficies usan el mismo despliegue de MongoDB. La superficie de la API escribe plantillas, informes y plazos. El worker actualiza un informe a medida que se completa.

En modo de un solo tenant, `MONGO_HOST` y `MONGO_NAME` son obligatorias al iniciar. En modo multi-tenant, cada tenant obtiene su propia base de datos, resuelta a partir del JWT de la solicitud. Esa vía falla en modo cerrado: una solicitud que lleva un tenant sin base de datos de tenant devuelve un error en lugar de tocar una base de datos compartida.

## RabbitMQ

***

Dos responsabilidades separadas comparten un broker.

### La cola de comandos de informes

Esta cola lleva el trabajo desde la superficie de la 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 la API publica, así que necesita las tres, además de su conexión al broker: `RABBITMQ_HOST`, `RABBITMQ_PORT_AMQP`, `RABBITMQ_DEFAULT_USER` y `RABBITMQ_DEFAULT_PASS`. El worker consume de la cola y necesita esa misma conexión, además de `RABBITMQ_GENERATE_REPORT_QUEUE`. Los objetos del broker deben existir antes de que cualquiera de los dos servicios inicie.

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

Un worker que falla al procesar un mensaje lo reintenta hasta cinco veces con backoff, y luego lo rechaza sin volver a encolarlo. Vincula un dead-letter exchange a la cola de comandos, de modo que un informe rechazado llegue a un lugar donde puedas inspeccionarlo.

### 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 configura el operador. El valor de referencia es `reporter.events`.

Configura ese exchange, `STREAMING_BROKERS` y `STREAMING_CLOUDEVENTS_SOURCE` siempre que `STREAMING_ENABLED=true`. Con el streaming apagado, ambas superficies inician con normalidad y no publican nada.

## Almacenamiento de objetos

***

Reporter usa un bucket compatible con S3, nombrado en `OBJECT_STORAGE_BUCKET`. Contiene dos tipos de objeto, cada uno 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, ambos prefijos están bajo el tenant que posee el objeto: `<tenantId>/templates/...` y `<tenantId>/reports/...`.

AWS S3, MinIO y SeaweedFS funcionan todos. Accede a SeaweedFS mediante su gateway S3. `OBJECT_STORAGE_USE_PATH_STYLE=true` es lo que esperan MinIO y SeaweedFS, y `OBJECT_STORAGE_DISABLE_SSL` permanece 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. Configura la expiración en el bucket, con la propia política de ciclo de vida del almacén de objetos, según la ventana que requieran tus reglas de retención.

<Warning>
  **Ancla la regla en el prefijo de informes que produce tu modo de tenancy.** En modo de un solo tenant, cada clave de informe empieza en `reports/`. 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 del alcance en cualquier caso: una regla que cubre todo el bucket también elimina las plantillas a partir de las cuales se renderizan tus informes.
</Warning>

## Redis o Valkey

***

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

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

## Fuentes de datos

***

Reporter lee los datos de generación de informes desde fuentes de datos de PostgreSQL y MongoDB en su registro persistido. Créalas y adminístralas mediante la [API de fuentes de datos](/es/reference/products/reporter/list-data-sources).

En modo de un solo tenant, un bloque opcional `DATASOURCE_{NAME}_*` siembra una entrada de registro administrada por el usuario al iniciar el Manager. Siembra la entrada solo cuando ese `configName` está ausente. Las ediciones y eliminaciones posteriores por la API tienen precedencia sobre el entorno. El modo multi-tenant omite la siembra por entorno y crea fuentes de datos por tenant mediante la API.

Tanto el Manager como el worker requieren la misma `DATASOURCE_CRED_ENC_KEY` persistente para proteger las credenciales del registro. Mantenla sin cambios a través de reinicios y despliegues, para que puedan seguir descifrando las credenciales almacenadas. Reporter también inicia sin ninguna configurada, y sirve plantillas, plazos y métricas.

## Dimensionamiento del worker

***

`RABBITMQ_NUMBERS_OF_WORKERS` establece cuántos trabajos de informes ejecuta en paralelo un proceso worker. Para escalar horizontalmente, agrega réplicas de worker y dirígelas según la profundidad de la cola de comandos.

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

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

## Modo de despliegue y TLS

***

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

<Warning>
  **El modo SaaS exige TLS en cada dependencia.** Si configuras `DEPLOYMENT_MODE=saas`, 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 configurar en producción. Omite esas verificaciones, y el stack de desarrollo local es el único lugar donde corresponde usarla.

## Verificaciones de inicio

***

Reporter valida su configuración antes de servir cualquier cosa. Cada verificación de abajo detiene el proceso, y el error nombra cada variable responsable.

| Disparador                                                                                                                                                                                        | Qué ve el operador                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Falta `SERVER_ADDRESS`, `REDIS_HOST`, alguna variable requerida de conexión o de cola de comandos de RabbitMQ, o `DATASOURCE_CRED_ENC_KEY` en la superficie de la API                             | La validación de configuración falla y enumera cada variable faltante.                |
| Falta alguna de `RABBITMQ_HOST`, `RABBITMQ_PORT_AMQP`, `RABBITMQ_DEFAULT_USER`, `RABBITMQ_DEFAULT_PASS`, `RABBITMQ_GENERATE_REPORT_QUEUE` o `DATASOURCE_CRED_ENC_KEY` en la superficie del worker | La validación de configuración falla y enumera cada variable faltante.                |
| Falta `MONGO_HOST` o `MONGO_NAME`, modo de un solo tenant                                                                                                                                         | La validación de configuración las nombra.                                            |
| `MULTI_TENANT_ENABLED=true` sin `MULTI_TENANT_URL` ni `MULTI_TENANT_SERVICE_API_KEY`                                                                                                              | La validación de configuración nombra la variable que necesita el runtime del tenant. |
| `STREAMING_ENABLED=true` sin `RABBITMQ_REPORT_EVENTS_EXCHANGE`, `STREAMING_BROKERS` y `STREAMING_CLOUDEVENTS_SOURCE`; las tres son obligatorias para un inicio con streaming habilitado           | El inicio se aborta en lugar de ejecutarse con eventos que no llegan a ningún lado.   |
| `DEPLOYMENT_MODE=saas` con una URL de dependencia en texto plano                                                                                                                                  | El inicio se aborta antes de que se abra cualquier conexión.                          |

<Note>
  **Una dependencia caída al arrancar no produce un pod silenciosamente roto.** `/health` responde 503 hasta que la autosonda de inicio se completa correctamente. El kubelet entonces reinicia el pod en lugar de enviarle tráfico.
</Note>

## Actualizaciones continuas

***

Al recibir `SIGTERM`, ambas superficies entran en un drenaje. La sonda `/readyz` responde 503 desde el momento en que llega la señal, antes de que los servidores empiecen a apagarse. Las solicitudes y los mensajes en curso terminan. Kubernetes elimina el pod de los endpoints del Service mientras todavía funciona.

Configura el período 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 saber qué reportan las sondas durante un drenaje.

## Próximos pasos

***

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

  <Card title="Configuración de BYOC" icon="sliders" href="/es/reference/byoc-configuration">
    Los bloques de configuración que comparten todos los productos de Lerian.
  </Card>

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

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