> ## 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.

# Deployment do Reporter

> Faça o deploy do Reporter: um binário com um seletor de modo de execução, MongoDB, a fila de comandos de relatório, armazenamento de objetos compatível com S3, Redis ou Valkey, dimensionamento do worker, e retenção de relatórios por meio de uma política de ciclo de vida do bucket.

O Reporter é entregue como um único binário com duas superfícies, e `RUN_MODE` seleciona quais superfícies um processo serve. A mesma imagem roda como a API, como o worker de relatórios, ou como ambas. Quatro dependências ficam por trás delas.

O Reporter lê os seus bancos de dados por meio de um motor de extração que roda dentro do processo do worker. Não existe um serviço de extração separado para o deploy.

## O que compõe o deploy

***

| Componente                   | Papel                                                                                          | Escala com                      |
| ---------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------- |
| **Superfície da API**        | API REST para templates, relatórios, prazos, e fontes de dados. Publica comandos de relatório. | Taxa de requisições.            |
| **Worker de relatórios**     | Consumidor da fila. Extrai os dados, renderiza o relatório, e grava o artefato.                | Profundidade da fila.           |
| **MongoDB**                  | Templates, relatórios, prazos, e o outbox durável de eventos.                                  | Volume de metadados.            |
| **RabbitMQ**                 | A fila de comandos de relatório, e a exchange de eventos de negócio.                           | Taxa de relatórios.             |
| **Armazenamento de objetos** | Fontes de template e relatórios renderizados. Compatível com S3.                               | Volume de artefatos e retenção. |
| **Redis ou Valkey**          | Locks de idempotência, cache de schema, e ciclo de vida do tenant.                             | Ambas as superfícies.           |

## Modos de execução

***

`RUN_MODE=api` serve toda operação REST, além de `/health`, `/readyz`, e `/version`, no endereço em `SERVER_ADDRESS`. `RUN_MODE=worker` consome a fila de comandos de relatório e serve `/health` e `/readyz` em `HEALTH_PORT`. `RUN_MODE=all` roda ambas as superfícies em um único processo.

Use `all` para desenvolvimento local. Em produção, faça o deploy das duas superfícies separadamente, para que a geração de relatórios escale por conta própria.

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

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

## MongoDB

***

Ambas as superfícies usam o mesmo deployment do MongoDB. A superfície da API grava templates, relatórios, e prazos. O worker atualiza um relatório conforme ele é concluído.

No modo single-tenant, `MONGO_HOST` e `MONGO_NAME` são obrigatórias na inicialização. No modo multi-tenant, cada tenant recebe seu próprio banco de dados, resolvido a partir do JWT na requisição. Esse caminho é fail-closed: uma requisição que carrega um tenant sem banco de dados de tenant retorna um erro em vez de tocar em um banco de dados compartilhado.

## RabbitMQ

***

Duas responsabilidades separadas compartilham um broker.

### A fila de comandos de relatório

Essa fila carrega trabalho da superfície da API para o worker. `RABBITMQ_EXCHANGE`, `RABBITMQ_GENERATE_REPORT_QUEUE`, e `RABBITMQ_GENERATE_REPORT_KEY` nomeiam a exchange, a fila, e a routing key. A superfície da API publica, então precisa das três variáveis mais sua conexão com o broker: `RABBITMQ_HOST`, `RABBITMQ_PORT_AMQP`, `RABBITMQ_DEFAULT_USER`, e `RABBITMQ_DEFAULT_PASS`. O worker consome da fila e precisa dessa mesma conexão mais `RABBITMQ_GENERATE_REPORT_QUEUE`. Os objetos do broker devem existir antes que qualquer um dos dois serviços seja iniciado.

O canal é interno ao Reporter. Para saber que um relatório terminou, inscreva-se nos eventos de negócio abaixo, ou faça polling no relatório.

Um worker que falha ao processar uma mensagem tenta de novo até cinco vezes com backoff, e depois a rejeita sem requeue. Vincule uma dead-letter exchange à fila de comandos, para que um relatório rejeitado vá parar em algum lugar onde você possa inspecioná-lo.

### A exchange de eventos

Eventos de negócio (`template.*`, `report.*`, `deadline.*`) vão para uma exchange que você nomeia em `RABBITMQ_REPORT_EVENTS_EXCHANGE`. O valor é configurado pelo operador. O valor de referência é `reporter.events`.

Defina essa exchange, `STREAMING_BROKERS`, e `STREAMING_CLOUDEVENTS_SOURCE` sempre que `STREAMING_ENABLED=true`. Com o streaming desligado, ambas as superfícies iniciam normalmente e não publicam nada.

## Armazenamento de objetos

***

O Reporter usa um bucket compatível com S3, nomeado em `OBJECT_STORAGE_BUCKET`. Ele guarda dois tipos de objeto, cada um sob seu próprio prefixo:

* a fonte do template, como `templates/<templateId>.tpl`
* o relatório renderizado, como `reports/<templateId>/<reportId>.<format>`

No modo multi-tenant, ambos os prefixos ficam sob o tenant que é dono do objeto: `<tenantId>/templates/...` e `<tenantId>/reports/...`.

AWS S3, MinIO, e SeaweedFS funcionam todos. Alcance o SeaweedFS pelo gateway S3 dele. `OBJECT_STORAGE_USE_PATH_STYLE=true` é o que MinIO e SeaweedFS esperam, e `OBJECT_STORAGE_DISABLE_SSL` permanece `false` fora do desenvolvimento local.

### Retenção de relatórios

O Reporter mantém todo relatório que renderiza, então o bucket cresce com o seu volume de relatórios. Defina expiração no bucket, com a política de ciclo de vida do próprio armazenamento de objetos, pela janela que as suas regras de retenção exigem.

<Warning>
  **Ancore a regra no prefixo de relatório que o seu modo de tenancy produz.** No modo single-tenant, toda chave de relatório começa em `reports/`. Uma regra nesse prefixo cobre o bucket. No modo multi-tenant, a chave carrega o tenant antes dela, então a regra precisa do prefixo completo `<tenantId>/reports/`, uma regra por tenant. Mantenha `templates/` fora do escopo de qualquer forma: uma regra que cobre o bucket inteiro também remove os templates a partir dos quais os seus relatórios são renderizados.
</Warning>

## Redis ou Valkey

***

`REDIS_HOST` é obrigatória na superfície da API. No worker, ela é obrigatória apenas quando `MULTI_TENANT_ENABLED=true`, onde armazena em cache a descoberta de tenant. O Redis sustenta o lock de idempotência na criação de relatórios, o cache de schema da fonte de dados, e as mensagens de ciclo de vida do tenant no modo multi-tenant.

O estado de idempotência vive no Redis, não na memória do processo, então as réplicas da API o compartilham. A mesma requisição de relatório enviada duas vezes, para duas réplicas, cria um relatório.

## Fontes de dados

***

O Reporter lê dados de relatório a partir de fontes de dados PostgreSQL e MongoDB no seu registro persistido. Crie e gerencie essas fontes por meio da [API de fontes de dados](/pt/reference/products/reporter/list-data-sources).

No modo single-tenant, um bloco opcional `DATASOURCE_{NAME}_*` popula uma entrada de registro gerenciada pelo usuário na inicialização do Manager. Ele popula a entrada apenas quando esse `configName` está ausente. Edições e exclusões posteriores pela API têm precedência sobre o ambiente. O modo multi-tenant pula a população via ambiente e cria fontes de dados por tenant por meio da API.

Tanto o Manager quanto o worker exigem a mesma `DATASOURCE_CRED_ENC_KEY` persistente para proteger as credenciais do registro. Mantenha-a inalterada entre reinicializações e deployments para que eles continuem decifrando as credenciais armazenadas. O Reporter também inicia sem nenhuma configurada, e serve templates, prazos, e métricas.

## Dimensionando o worker

***

`RABBITMQ_NUMBERS_OF_WORKERS` define quantas tarefas de relatório um processo worker executa em paralelo. Para escala horizontal, adicione réplicas de worker e direcione-as pela profundidade da fila de comandos.

A saída em PDF é renderizada por um pool de navegadores headless: `PDF_POOL_WORKERS` renderizações simultâneas, cujo padrão é 2, cada uma limitada por `PDF_TIMEOUT_SECONDS`, cujo padrão é 90. Dimensione a memória do worker em função desse pool, não apenas das linhas que um relatório lê. Os demais formatos de saída não o utilizam.

Todo relatório também carrega limites fixos de extração. São 10 fontes de dados, 50 tabelas por fonte de dados, e 200 campos por tabela. Também cobrem 4 fontes de dados lidas por vez, um prazo de 300 segundos, e um teto de 100 MiB nos dados extraídos. As variáveis `ENGINE_*` os alteram.

## Modo de deployment e TLS

***

`DEPLOYMENT_MODE` declara a variante do deployment: `local`, `byoc`, ou `saas`. Ele marca a resposta de `/readyz`, e em `saas` ele impõe TLS.

<Warning>
  **O modo SaaS exige TLS em toda dependência.** Defina `DEPLOYMENT_MODE=saas` e uma URL de MongoDB, RabbitMQ, Redis, armazenamento de objetos, ou Tenant Manager sem criptografia interrompe o processo. Ele para antes de qualquer conexão abrir.
</Warning>

Deixe `ALLOW_INSECURE_TLS` não definida em produção. Ela contorna essas verificações, e a stack de desenvolvimento local é o único lugar para ela.

## Verificações de inicialização

***

O Reporter valida sua configuração antes de servir qualquer coisa. Cada verificação abaixo interrompe o processo, e o erro nomeia cada variável responsável.

| Gatilho                                                                                                                                                                                                    | O que o operador vê                                                            |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `SERVER_ADDRESS`, `REDIS_HOST`, qualquer variável obrigatória de conexão com o RabbitMQ ou de fila de comandos, ou `DATASOURCE_CRED_ENC_KEY` ausente na superfície da API                                  | A validação de configuração falha e lista cada variável ausente.               |
| Qualquer uma entre `RABBITMQ_HOST`, `RABBITMQ_PORT_AMQP`, `RABBITMQ_DEFAULT_USER`, `RABBITMQ_DEFAULT_PASS`, `RABBITMQ_GENERATE_REPORT_QUEUE`, ou `DATASOURCE_CRED_ENC_KEY` ausente na superfície do worker | A validação de configuração falha e lista cada variável ausente.               |
| `MONGO_HOST` ou `MONGO_NAME` ausente, modo single-tenant                                                                                                                                                   | A validação de configuração as nomeia.                                         |
| `MULTI_TENANT_ENABLED=true` sem `MULTI_TENANT_URL` ou `MULTI_TENANT_SERVICE_API_KEY`                                                                                                                       | A validação de configuração nomeia a variável que o runtime de tenant precisa. |
| `STREAMING_ENABLED=true` sem `RABBITMQ_REPORT_EVENTS_EXCHANGE`, `STREAMING_BROKERS`, e `STREAMING_CLOUDEVENTS_SOURCE` — as três são obrigatórias para uma inicialização com streaming habilitado           | A inicialização aborta em vez de rodar com eventos que não vão a lugar nenhum. |
| `DEPLOYMENT_MODE=saas` com uma URL de dependência sem criptografia                                                                                                                                         | A inicialização aborta antes de qualquer conexão abrir.                        |

<Note>
  **Uma dependência fora do ar na inicialização não produz um pod silenciosamente quebrado.** `/health` responde 503 até que a auto-verificação de inicialização seja bem-sucedida. O kubelet então reinicia o pod em vez de enviar tráfego a ele.
</Note>

## Atualizações contínuas

***

Ao receber `SIGTERM`, ambas as superfícies entram em drain. O probe `/readyz` responde 503 a partir do momento em que o sinal chega, antes que os servidores comecem o shutdown. Requisições em andamento e mensagens em andamento terminam. O Kubernetes remove o pod dos endpoints do Service enquanto ele ainda funciona.

Defina o termination grace period acima da duração da sua renderização de relatório mais longa. Veja a [referência de saúde e readiness](/pt/reference/health-and-readiness) para o que os probes reportam durante um drain.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Variáveis de ambiente" icon="gear" href="/pt/products/reporter/reporter-environment-variables">
    Toda variável do Reporter, por categoria.
  </Card>

  <Card title="Configuração do BYOC" icon="sliders" href="/pt/reference/byoc-configuration">
    Os blocos de configuração que todo produto Lerian compartilha.
  </Card>

  <Card title="Saúde e readiness" icon="heart-pulse" href="/pt/reference/health-and-readiness">
    O contrato de probe e o que cada resposta significa.
  </Card>

  <Card title="Conecte o Reporter ao Midaz" icon="link" href="/pt/products/reporter/connecting-reporter-to-midaz">
    Aponte o Reporter para um banco de dados do Midaz e renderize seu primeiro relatório.
  </Card>
</CardGroup>
