RUN_MODE seleciona quais superfícies um processo atende, então a mesma imagem roda como a API, como o worker de relatórios, ou como os dois. Quatro dependências ficam atrás delas.
O Reporter lê os seus bancos de dados por um motor de extração que roda dentro do processo worker. Não há um serviço de extração separado para implantar.
O que você implanta
Modos de execução
O
RUN_MODE=api atende todas as operações REST, mais /health, /readyz e /version, no endereço definido em SERVER_ADDRESS. O RUN_MODE=worker consome a fila de comandos de relatório e atende /health e /readyz na HEALTH_PORT. O RUN_MODE=all roda as duas superfícies em um só processo.
Use all para desenvolvimento local. Em produção, implante as duas superfícies em separado, para a geração de relatórios escalar por conta própria.
MongoDB
As duas superfícies usam a mesma implantação de MongoDB. A superfície de API grava templates, relatórios e prazos; o worker atualiza um relatório à medida que o conclui. Em modo single-tenant,
MONGO_HOST e MONGO_NAME são obrigatórias na inicialização. Em modo multi-tenant, cada tenant recebe o próprio banco, resolvido a partir do JWT da requisição. Esse caminho falha de forma fechada: uma requisição que carrega um tenant sem banco de tenant retorna um erro em vez de tocar um banco compartilhado.
RabbitMQ
Dois assuntos distintos dividem um mesmo broker.
A fila de comandos de relatório
Essa fila leva o trabalho da superfície de API até o worker.RABBITMQ_EXCHANGE, RABBITMQ_GENERATE_REPORT_QUEUE e RABBITMQ_GENERATE_REPORT_KEY nomeiam o exchange, a fila e a routing key. A superfície de API publica, então precisa das três. O worker só consome, então precisa de RABBITMQ_GENERATE_REPORT_QUEUE sozinha. As duas superfícies precisam da conexão com o broker em si, e os objetos precisam existir antes de os serviços subirem.
O canal é interno do Reporter. Para saber que um relatório terminou, assine os eventos de negócio abaixo, ou consulte o relatório.
Um worker que falha uma mensagem tenta de novo até cinco vezes com backoff, e depois a rejeita sem reenfileirar. Ligue um dead-letter exchange à fila de comandos, para um relatório rejeitado cair em um lugar que você possa inspecionar.
O exchange de eventos
Os eventos de negócio (template.*, report.*, deadline.*) vão para um exchange que você nomeia em RABBITMQ_REPORT_EVENTS_EXCHANGE. O valor é definido pelo operador; reporter.events é o valor de referência.
Defina esse exchange, STREAMING_BROKERS e STREAMING_CLOUDEVENTS_SOURCE sempre que STREAMING_ENABLED=true. Com o streaming desligado, as duas superfícies sobem normalmente e não publicam nada.
Object storage
O Reporter usa um único bucket compatível com S3, nomeado em
OBJECT_STORAGE_BUCKET. Ele guarda dois tipos de objeto, cada um sob o seu próprio prefixo:
- a fonte do template, como
templates/<templateId>.tpl - o relatório renderizado, como
reports/<templateId>/<reportId>.<format>
<tenantId>/templates/... e <tenantId>/reports/....
AWS S3, MinIO e SeaweedFS funcionam. Alcance o SeaweedFS pelo gateway S3 dele. OBJECT_STORAGE_USE_PATH_STYLE=true é o que MinIO e SeaweedFS esperam, e OBJECT_STORAGE_DISABLE_SSL fica em false fora do desenvolvimento local.
Retenção de relatórios
O Reporter guarda todo relatório que renderiza, então o bucket cresce com o seu volume de relatórios. Defina a expiração no bucket, com a política de ciclo de vida do próprio object storage, sobre a janela que as suas regras de retenção exigem.Redis ou Valkey
REDIS_HOST é obrigatória na superfície de API. No worker ela só é obrigatória quando MULTI_TENANT_ENABLED=true, onde faz cache da descoberta de tenants. O Redis sustenta a trava de idempotência na criação de relatórios, o cache de esquemas das fontes de dados e as mensagens de ciclo de vida de tenants em modo multi-tenant.
O estado de idempotência vive no Redis, e não na memória do processo, então as réplicas de API o compartilham. A mesma requisição de relatório enviada duas vezes, para duas réplicas, cria um relatório só.
Fontes de dados
O Reporter lê os dados dos relatórios de fontes de dados PostgreSQL e MongoDB declaradas no ambiente, um bloco
DATASOURCE_{NAME}_* por fonte. Veja Variáveis de ambiente para o bloco.
Não existe uma API que registre uma fonte de dados, então uma fonte nova é uma mudança de configuração e um reinício. O Reporter também sobe sem nenhuma configurada, e atende templates, prazos e métricas.
Dimensionar o worker
RABBITMQ_NUMBERS_OF_WORKERS define quantos trabalhos de relatório um processo worker roda em paralelo. Para escala horizontal, adicione réplicas do worker e comande-as pela profundidade da fila de comandos.
A saída em PDF é renderizada por um pool de navegador headless: PDF_POOL_WORKERS renderizações concorrentes, com padrão 2, cada uma limitada por PDF_TIMEOUT_SECONDS, com padrão 90. Dimensione a memória do worker contra esse pool, e não apenas contra as linhas que um relatório lê. Os demais formatos de saída não o usam.
Todo relatório carrega também limites fixos de extração. Eles são 10 fontes de dados, 50 tabelas por fonte de dados e 200 campos por tabela, com 4 fontes de dados lidas por vez, um prazo de 300 segundos e um teto de 100 MiB de dados extraídos. As variáveis ENGINE_* mudam esses valores.
Modo de implantação e TLS
O
DEPLOYMENT_MODE declara o sabor da implantação: local, byoc ou saas. Ele etiqueta a resposta de /readyz e, em saas, exige TLS.
Deixe ALLOW_INSECURE_TLS sem definir em produção. Ela ignora essas checagens, e a stack de desenvolvimento local é o único lugar para ela.
Checagens de inicialização
O Reporter valida a configuração antes de atender qualquer coisa. Cada checagem abaixo interrompe o processo, e o erro nomeia todas as variáveis em falta.
Uma dependência fora do ar no boot não produz um pod quebrado em silêncio. O
/health retorna 503 até a autossondagem de inicialização passar. O kubelet então reinicia o pod, em vez de mandar tráfego para ele.Atualizações contínuas
Em
SIGTERM, as duas superfícies entram em drenagem. O /readyz responde 503 desde o momento em que o sinal chega, antes de os servidores começarem o desligamento, e as requisições e mensagens em voo terminam. O Kubernetes remove o pod dos endpoints do Service enquanto ele ainda funciona.
Defina o período de graça de término acima da sua renderização de relatório mais longa. Veja a referência de saúde e prontidão para o que as sondas reportam durante uma drenagem.
Próximos passos
Variáveis de ambiente
Cada variável do Reporter, por categoria.
Configuração BYOC
Os blocos de configuração que todo produto Lerian compartilha.
Saúde e prontidão
O contrato das sondas e o que cada resposta significa.
Conectar o Reporter ao Midaz
Aponte o Reporter para um banco do Midaz e renderize seu primeiro relatório.

