Pular para conteúdo

Instalação completa do ambiente local

Esta jornada instala o backend no Kind, com MongoDB, Valkey, RabbitMQ, PostgreSQL, MinIO, Elasticsearch, OpenTelemetry, Keycloak e o Platform API Mock. É um ambiente experimental de desenvolvimento. DEV, STAGING e PROD pertencem ao TOTVS Apps.

Instalação nova e cluster existente

Os comandos de instalação, carregamento de imagens e limpeza abaixo modificam o ambiente. Não os execute sobre um cluster existente sem revisar os valores e o plano de aplicação. Credenciais geradas para uma instalação nova não substituem automaticamente as credenciais dos bancos existentes.

O registro de validação distingue builds e verificações estáticas dos cenários funcionais ainda pendentes de execução no cluster.

1. Preparar a máquina e obter o código

Use Docker com containers Linux, Git, Python 3.12 ou superior, Kind, kubectl, Helm 3 e Helmfile. helmfile apply também utiliza o plugin Helm Diff. Consulte Preparar o ambiente para instalação das ferramentas. As versões utilizadas na revisão foram Docker 28.4, Helm 3.18.6 e Helmfile 1.1.7; isso não constitui uma matriz completa de compatibilidade.

No Windows, use Docker Desktop com WSL2 e PowerShell, ou execute toda a jornada dentro do WSL2. No Ubuntu, use Docker Engine e o perfil local-ubuntu. Não misture contexts Docker, arquivos de credenciais e executáveis de ambientes diferentes durante a instalação.

Obtenha os repositórios backend autorizados na organização e mantenha a organização services/ e infra/totvs-gateway-infra-local/. A relação exata dos repositórios, commits e Dockerfiles está em install/local-images.json. Os scripts recusam construir um serviço cujo HEAD difira do commit revisado nesse arquivo. Para uma nova versão, revise e atualize esse inventário e as tags em conjunto.

Execute os comandos seguintes na raiz de totvs-gateway-infra-local:

python -m pip install -r scripts/local/requirements.txt
python scripts/local/images.py check
docker info
kind get clusters
kubectl config current-context
helm version
helmfile --version
helm plugin list

O cluster declarado possui quatro nós. Não há dimensionamento mínimo validado para executar todos os serviços simultaneamente. Reserve capacidade para JVMs, bancos, Elasticsearch e builds; confira requests/limits nos manifests antes de aplicar. Falta de capacidade não deve ser corrigida desabilitando probes ou segurança.

2. Preparar valores privados e imagens

python scripts/local/prepare.py
python scripts/local/images.py build

prepare.py cria .local/values.yaml, ignorado pelo Git, com credenciais aleatórias e referências às imagens locais. Não sobrescreve arquivo existente. Guarde esse arquivo com acesso restrito e reutilize-o nas atualizações. No Windows, confira também as permissões NTFS da pasta; chmod não substitui a revisão das ACLs.

O build exporta os commits com git archive para uma pasta temporária em .local/build; não compila dentro dos repositórios dos microserviços. Java usa Maven 3.9.11/JDK 21 em container, executa verify e utiliza o Dockerfile JVM existente. Broker e Security Checker utilizam seus Dockerfiles locais. Discovery, Auth Provider, Router e Outbox Dispatcher utilizam o Dockerfile Go do repositório de infraestrutura, com toolchain/entrypoint declarados no inventário e execução de go test ./.... Cache Monitor utiliza o Dockerfile cron existente.

As imagens são JVM, não native: o suporte a JDWP depende disso. Os Dockerfiles dos serviços são preservados. As bases e dependências precisam estar acessíveis pela rede; tags fixadas não garantem reprodução byte a byte de bases externas mutáveis. Falhas de testes ou dependências privadas interrompem o build e devem ser investigadas, sem saltar os testes para declarar sucesso.

Para construir apenas um componente:

python scripts/local/images.py build --only json-handler

O inventário contém 22 imagens de componentes backend, incluindo Outbox Dispatcher e Cache Monitor, além de Keycloak e mocks. Todos os charts atualmente habilitados pelo agregador permanecem contemplados. Tunnel e Web Pages não são adicionados artificialmente ao agregador.

3. Criar o Kind e configurar o acesso

Somente para uma instalação nova, após confirmar a ausência de cluster com o mesmo nome:

kind create cluster --config kind/kind-config.yaml
kubectl --context kind-totvs-gateway get nodes
python scripts/local/images.py load --cluster totvs-gateway

O arquivo Kind mapeia as portas 80/443 do host para NodePorts 30080/30443. O perfil Windows utiliza esses NodePorts. No Ubuntu, o perfil utiliza MetalLB/LoadBalancer: defina global.metallb.ipRange em .local/values.yaml com um intervalo livre e alcançável da rede Docker efetivamente utilizada. O perfil recusa renderizar um pool vazio; o Ingress recebe um endereço desse pool, sem IP de uma máquina antiga fixado nos values. Confira a rede com docker network inspect kind e evite endereços usados por nós, gateway ou outros containers.

Configure no arquivo hosts da máquina api.gateway.local.test, auth.gateway.local.test e company-a.gateway.local.test. No Windows, a entrada aponta para 127.0.0.1 se o mapeamento de portas do Docker Desktop estiver disponível. No Ubuntu/MetalLB, utilize o IP atribuído ao Service do Ingress. Arquivos hosts não aceitam wildcard. O acesso por IP sem o Host correto não seleciona o Ingress esperado.

4. Renderizar, revisar e instalar

Os valores são aplicados nesta ordem: install/common/local-platform.yaml, perfil em install/NGiNX/environments/, .local/values.yaml. O último arquivo é privado. Não aplique apenas o arquivo do perfil diretamente com Helm: ele contém somente as diferenças entre sistemas operacionais.

helmfile -f install/NGiNX/helmfile.yaml --environment local-win list
helmfile -f install/NGiNX/helmfile.yaml --environment local-win template > .local/rendered.yaml

Substitua local-win por local-ubuntu quando aplicável. Os manifests renderizados contêm Secrets; não os publique. Revise imagens, namespaces, credenciais, volumes e endpoints antes da aplicação.

Após autorização para modificar o cluster:

helmfile -f install/NGiNX/helmfile.yaml --environment local-win apply

O DAG needs estabelece as dependências de instalação:

Grupo Componentes e responsabilidade
Base Namespaces, permissões e recursos de base; MetalLB no Ubuntu
Entrada Ingress NGINX; a entrada pública mantém a chamada ao Security Checker
Persistência e processamento MongoDB, Valkey, RabbitMQ, PostgreSQL, MinIO
Observabilidade Elasticsearch e OpenTelemetry Collector
Simulação externa Release mocks, com workload no namespace totvs-gateway
Plataforma Release totvs-gateway-server: microserviços, Keycloak e Job de importação dos realms

As versões dos charts externos estão fixadas no Helmfile. O Keycloak é parte do release da plataforma, não um release independente. Helm aguarda readiness e Jobs conforme helmDefaults. Um Pod Ready não comprova que as integrações funcionam.

Os namespaces das dependências são mongodb, valkey, rabbitmq, postgresql, minio, data-lake, telemetry, ingress-nginx e keycloak. Os microserviços e o mock ficam em totvs-gateway. Os releases base, mocks e agregador têm metadados Helm no namespace default; isso não muda os namespaces declarados pelos templates.

5. Keycloak local e autenticação

O bootstrap configura o realm técnico usado pelo Security Checker e o realm local. Neste último, o client confidencial account habilita os fluxos já previstos no projeto e emite apps: ["ipaas"], companyId e userIdpId. Os usuários locais A/B pertencem a tenants distintos. Seus nomes, senhas e client secret estão em global.keycloak.bootstrap no arquivo privado; não há senha a copiar deste tutorial.

O issuer local é http://auth.gateway.local.test/realms/local. O BFF consulta as chaves em http://keycloak.keycloak.svc.cluster.local/realms/local/protocol/openid-connect/certs. Auth Provider usa discovery/JWKS internos e issuer configurado por realm. O Keycloak habilita backchannel dinâmico para clientes internos, mantendo o hostname público completo para o issuer. Não substitua o JWT por um token do mock.

kubectl --context kind-totvs-gateway -n keycloak rollout status deployment/keycloak
kubectl --context kind-totvs-gateway -n totvs-gateway get jobs -l app=keycloak-config-cli-import
kubectl --context kind-totvs-gateway -n totvs-gateway logs -l job-name=keycloak-config-cli-import-1 -c keycloak-config-cli

O sufixo do Job é a revisão Helm; consulte get jobs antes de selecionar o nome. Jobs concluídos têm TTL de 600 segundos. Não procure indefinidamente um Job já removido pelo TTL; confira os realms e o token.

O realm ERP depende do provider totvs-form-parameter-claim-protocol-mapper, cujo JAR não está disponível neste workspace. global.keycloak.erpEnabled: false exclui apenas essa importação, sem substituir o provider e sem desligar validação de tokens. Integrações ERP com claims derivados de parâmetros de formulário permanecem indisponíveis.

6. Mocks e dependências externas

O Platform API Mock já simula recursos, aplicações, serviços, ambientes e validação de recursos do iPaaS, além de Accounts/OAuth e do destino /teste/service. A instalação agora utiliza o chart existente pelo Helmfile. Core, BFF e Builder recebem URLs internas do mock; o ambiente env-1 aponta para http://mocks:8080, e resource-1 descreve GET /teste/service, com isErp: false.

O mock de Authenticator implementa GET /authenticator/v1/roles/by-user-tenant, com userCode/tenantCode e resposta features[].resources[].group.code/code. local-user-a no tenant company-a recebe a fixture VariableV2/VariableV2.create; outros pares recebem lista vazia, e ausência de Bearer retorna 401. Essa permissão vem do teste do BFF, não representa um endpoint administrativo protegido já em uso.

O mock verifica a presença de Bearer, não a assinatura criptográfica: a validação real de JWT continua no BFF. Não exponha o mock como serviço corporativo de autorização.

kubectl --context kind-totvs-gateway -n totvs-gateway port-forward service/mocks 18084:8080

Em outro terminal, consulte http://127.0.0.1:18084/teste/service e os mappings em http://127.0.0.1:18084/__admin/mappings. Finalize o port-forward após a inspeção. Diagramas iPaaS, ERP, serviços corporativos e integrações não cobertas pelos mappings não são considerados simulados apenas porque o mock está disponível.

7. Validar infraestrutura e aplicação

kubectl --context kind-totvs-gateway get nodes
kubectl --context kind-totvs-gateway get pods -A
kubectl --context kind-totvs-gateway get services -A
kubectl --context kind-totvs-gateway -n totvs-gateway get deployments
kubectl --context kind-totvs-gateway -n totvs-gateway get events --sort-by=.lastTimestamp

Verifique separadamente readiness dos bancos, conexão dos serviços e processamento funcional. O endpoint do BFF é /gateway/q/health/ready; não presuma que todos os serviços Java/Go compartilham o mesmo caminho. Consulte as probes de cada Deployment e Diagnóstico.

Cenário B — Control Plane

Após autorização e instalação, execute:

python scripts/local/check_control_plane.py

O script emite token pelo Keycloak local, confere os claims esperados, consulta GET /gateway/api/v1/gateways no BFF com Bearer e x-tenant-id, e verifica que a mesma entrada sem token é rejeitada. O token de curta duração fica em .local/access-token.txt para a etapa seguinte; não é impresso. Decodificar os claims não verifica a assinatura: essa verificação pertence ao BFF.

Limitação de autorização por recurso: no BFF atual, os endpoints administrativos analisados não aplicam @RequiresResource. Portanto, sucesso nessa consulta não comprova a aplicação da permissão retornada pelo Authenticator. Não utilize sysadmin, não desligue RESOURCE_AUTHORIZATION_ENABLED e não regrida a versão do serviço. A conclusão integral dessa parte do cenário B depende de evolução do BFF fora do escopo deste trabalho.

Cenário A — Data Plane

Este roteiro prepara uma rota administrativa autenticada, publica sua revisão e utiliza a entrada pública protegida pelo Security Checker. Execute depois do cenário B. Os comandos PowerShell abaixo utilizam os DTOs atuais do BFF/Core; ainda precisam de execução integrada autorizada para confirmar o resultado.

$api = 'http://api.gateway.local.test/gateway/api/v1'
$headers = @{ Authorization = 'Bearer ' + (Get-Content .local/access-token.txt -Raw); 'x-tenant-id' = 'company-a' }
function Invoke-GatewayJson($method, $path, $body) {
    Invoke-RestMethod -Method $method -Uri "$api$path" -Headers $headers -ContentType 'application/json' -Body ($body | ConvertTo-Json -Depth 15)
}
$suffix = Get-Date -Format yyyyMMddHHmmss
$routePassword = [guid]::NewGuid().ToString('N')
$auth = Invoke-GatewayJson POST '/authorizations' @{ name = "Local $suffix"; type = 'BASIC'; userName = 'local-probe'; password = $routePassword }
$gateway = Invoke-GatewayJson POST '/gateways' @{ name = "Local $suffix"; description = 'Validacao do destino mock'; basePath = "/local-$suffix"; enabled = $true; authentication = @{ id = $auth.id; type = 'BASIC' } }
$category = Invoke-GatewayJson POST "/gateways/$($gateway.id)/categories" @{ name = 'Validacao local' }
$route = Invoke-GatewayJson POST "/gateways/$($gateway.id)/routes" @{ name = 'Destino mock'; categoryId = $category.id }
$null = Invoke-GatewayJson PATCH "/gateways/$($gateway.id)/routes/$($route.id)" @{
    enabled = $true
    client = @{ path = '/probe'; method = 'GET'; authentication = @{ id = $auth.id; type = 'BASIC'; heritageType = 'OWN' } }
    ipaasResource = @{ applicationId = '9ed673d9-8791-45dd-9409-8d35dd16e85b'; serviceId = '9ed673d9-8791-45dd-9409-8d35dd16e85b'; resourceId = 'resource-1'; environmentId = 'env-1' }
}
Invoke-RestMethod -Method POST -Uri "$api/gateways/$($gateway.id)/routes/$($route.id)/complete" -Headers $headers
Invoke-RestMethod -Method POST -Uri "$api/gateways/$($gateway.id)/revision/$($gateway.revisionId)/promote" -Headers $headers
$basic = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("local-probe:$routePassword"))
Invoke-RestMethod -Uri "http://company-a.gateway.local.test/local-$suffix/probe" -Headers @{ Authorization = "Basic $basic" }

BASIC é um mecanismo real do Security, configurado apenas nessa nova rota; não desliga JWT do BFF nem a autenticação da entrada pública. Utilize esse HTTP somente no ambiente local. Repita a chamada pública sem Authorization e confirme a rejeição. Compare o corpo recebido com o mapping /teste/service e confirme no journal do WireMock que o destino foi chamado; HTTP 200 isolado não prova o caminho completo. Registre os IDs criados para remoção posterior pelas APIs administrativas, sem apagar collections diretamente.

Se qualquer etapa de configuração/publicação falhar, interrompa o roteiro e registre o erro. Não altere o banco manualmente nem remova validações para forçar a publicação. Falhas desse roteiro representam uma pendência funcional, não uma instalação completa validada.

8. Desenvolvimento e atualização

Os manifests locais usam imagens gateway-local/* com política Never para os serviços e o mock. Construa e carregue a tag em todos os nós antes de aplicar. Não misture tags carregadas localmente com imagePullPolicy: Always. Keycloak utiliza IfNotPresent e também deve ser carregado. Imagens de terceiros continuam sendo obtidas dos respectivos registries públicos.

Para atualizar código, revise commits/tags em install/local-images.json e as referências correspondentes em .local/values.yaml, construa, carregue e reaplique o Helmfile. Não gere novas credenciais para atualizar uma imagem. Reutilizar a mesma tag pode exigir rollout explícito; prefira tags novas associadas ao commit.

global.devMode já habilita JDWP nos charts compatíveis. Consulte Debug remoto Java, sem modificar Dockerfiles. Continue com Primeiro deploy local, Imagens Docker e Deploy no Kind.

9. Diagnóstico

Sintoma Verificação
Kind não inicia Docker Linux ativo, portas 80/443 livres, memória/disco e context corretos
ErrImageNeverPull Tag exata construída e carregada em todos os nós; confira install/local-images.json
ImagePullBackOff Registry da imagem externa acessível; imagens locais não devem utilizar Always
Ubuntu sem EXTERNAL-IP Pool MetalLB real, não vazio, sem conflito e alcançável pelo host
CrashLoopBackOff kubectl logs --previous, configuração, requests/limits e dependências; não desligue probes
Falha Mongo/Valkey/Rabbit Service/DNS, Secret e credencial do banco efetivamente instalado; values novos não rotacionam bancos antigos
Keycloak não importa Logs do Job da revisão atual, PostgreSQL, imagens do bootstrap e realm ERP desabilitado sem seu provider
Token rejeitado Issuer, expiração, JWKS, apps, companyId, userIdpId e tenant; não imprima tokens em logs
Mock retorna 404 Método, path, query e mapping exatos; não assuma que todos os contratos externos têm fixture
Rota não publica Categoria, configuração iPaaS, autenticação e estado PUBLISHABLE antes da promoção do gateway
BFF responde, mas permissões não mudam Limitação de aplicação de @RequiresResource; não concluir que o mock está sendo consultado
Observabilidade incompleta Conexão Collector/Elasticsearch, exportadores e recursos; saúde HTTP não comprova ingestão

10. Limpeza e preservação de dados

Um rollout não é um backup. Alguns values históricos de dependências desabilitam persistência; confira os PVCs e volumes renderizados antes de reiniciar bancos. Helm rollback também não restaura os dados de bancos nem desfaz importações do Keycloak.

Somente após autorização para a remoção desejada:

helm --kube-context kind-totvs-gateway uninstall totvs-gateway-server -n default
helm --kube-context kind-totvs-gateway uninstall mocks -n default

Esses comandos removem os recursos desses releases; não são uma forma de preservar todos os dados. Para destruir integralmente um cluster descartável, kind delete cluster --name totvs-gateway remove seus nós e armazenamento local. Não execute no cluster existente desta revisão. Apague tokens temporários após uso; mantenha os valores privados necessários para recuperar os bancos que forem preservados.

Base técnica e limites

As fontes de configuração são kind/kind-config.yaml, install/NGiNX/helmfile.yaml, install/common/local-platform.yaml, os charts em helm-releases/ e install/local-images.json. Os contratos do roteiro estão em GatewayResource, RouteResource, AuthorizationResource e DTOs associados no BFF; GatewayController, RouteController e seus DTOs no Core; e nos mappings do Platform API Mock. A revisão de referência do BFF é 4c0161acad09968433589f132dd640dcf624bec9.

Istio e Kubernetes Gateway API continuam estudos separados, não são pré-requisitos desta jornada NGINX. ERP, diagramas iPaaS e integrações corporativas não simuladas continuam limitados. A disponibilidade de todos os Pods não elimina essas limitações.