Empacotamento da imagem

O que vai (e o que não vai) para a imagem do Oon-App, como assets e dependências devem ser declarados e como a imagem é validada antes do deploy.

O builder governado de delivery gera uma imagem com backend Node e frontend estático servido por Nginx. Estar no checkout não significa estar na imagem.

Origem Destino / efeito
backend/ /app/backend/ — código, manifestos e assets de runtime
backend/package*.json Instalação com --omit=dev
frontend/ npm run build; fontes não vão para o runtime
frontend/dist/ /usr/share/nginx/html/
central.app.json /app/central.app.json (e no build do frontend)
Templates de e-mail declarados Mesmo caminho relativo a /app (traversal/symlink externo rejeitado)
docs/, .ooncore/, arquivos da raiz Não copiados
node_modules, .git, .env*, .npmrc, *.pem, *.key Excluídos
frontend/.env.production Única exceção .env, gerada pelo executor, sem segredos

O .dockerignore do App é preservado e acrescido de exclusões obrigatórias.

Frontend estático

O Nginx da imagem serve frontend/dist/ com try_files $uri $uri/index.html $uri.html /index.html:

Requisição Resposta
Arquivo existente (/assets/app.js, /llms.txt) o arquivo
/rota com dist/rota/index.html ou dist/rota.html essa página, sem redirect
Qualquer outro caminho fora de /api/ index.html (fallback da SPA)

Assim um App pode pré-renderizar páginas no build (HTML legível por buscadores e crawlers de IA, que não executam JavaScript) sem mudar as rotas da SPA. Redirects do próprio Nginx são relativos (absolute_redirect off) e respostas de texto saem com charset=utf-8; /api/ não é afetado.

Assets e dependências

backend/src/assets/omie/catalog.json
const catalog = require("../assets/omie/catalog.json");

Carregar não é copiar

O bootstrap carrega central.config.js, os manifestos e os .js/.cjs de src/models, validations, triggers, routes, pipelines, documents e hooks. src/services e src/assets entram pelos imports. Não mantenha scripts de teste executáveis nos diretórios autocarregados.

Validação da imagem

Após o build, a mesma imagem (ID sha256) é iniciada com:

  • entrypoint normal, usuário não privilegiado, filesystem somente leitura;
  • diretórios temporários e limites de CPU/memória/processos com timeout;
  • MongoDB descartável, apenas loopback, sem rede externa, credenciais reais, socket Docker ou mounts do host;
  • readiness aprovada em três observações consecutivas.

A morte do backend ou do Nginx encerra o contêiner. Liveness consulta o backend sem exigir banco; readiness exige banco. Perda transitória do banco não reinicia o pod por liveness.

{
  "health": {
    "livePath": "/health/live",
    "readyPath": "/api/health/ready",
    "versionPath": "/api/health/version"
  }
}

Falha impede a exportação da imagem para deploy. O Workspace recebe etapa, categoria, código, caminho e orientação — sem logs ou stack brutos. 502/timeout isolados não comprovam erro de código.

Essa prova cobre carregamento e inicialização. Não substitui testes funcionais, autenticação/tenancy, integrações reais, imports preguiçosos acionados por requisições nem a homologação Dev → HML → Produção.