Pular para conteúdo

Injeção de config no Coolify

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-01

O que é

Ao provisionar uma feature (POST /api/setup/provision), o auth entrega o resultado client-grade no recurso Coolify do app-alvo, gravando cada valor como env <PROVIDER>_<KEY>. Ex.: provisionar garage para o app auth injeta GARAGE_BUCKET no recurso auth no Coolify.

Exceção — nome canônico de SDK. A derivação <PROVIDER>_<KEY> vale quando quem lê o env é código nosso. Quando o consumidor é um SDK de terceiro que já tem nome de env canônico, o canônico ganha — senão o app precisaria de código só para traduzir o nome. Hoje há uma exceção, na tabela ENVS_CANONICOS do CoolifyClient:

provider.key env injetado por quê
glitchtip.dsn SENTRY_DSN (não GLITCHTIP_DSN) GlitchTip é Sentry-compatível e os apps usam o SDK do Sentry (Java e Dart), que lê SENTRY_DSN do ambiente por convenção. Mesmo mapeamento que o Dockerfile Flutter já faz no --dart-define.

É o mecanismo de entrega para apps servidor (Coolify): o client-grade que o app consome em runtime vira env. Para mobile/local (sem Coolify) é no-op — o client-grade vai só no app.json (entregue via --dart-define no build).

Spike resolvido: a API do Coolify v4 tem set-env idempotente (PATCH /applications/{uuid}/envs/bulk, casa por key) — então a Fase 4 é um injetor real, não o plano B de "só avisa o drift".

Como funciona (decisão Fase 4, opção A)

  1. Configurado? Sem COOLIFY_API_URL/COOLIFY_API_TOKEN → no-op.
  2. É app servidor? Sem production_url no catálogo → no-op (mobile).
  3. Acha o recurso por domínio (decisão 3.4b): GET /applications → casa fqdn == production_url (compara só o host, ignora esquema e múltiplos fqdn separados por vírgula). Não achou → loga aviso e para (não injeta).
  4. Upsert idempotente: PATCH /applications/{uuid}/envs/bulk com {"data":[{"key":"<PROVIDER>_<KEY>","value":"…","is_shown_once":true}]}.

Best-effort: falha na injeção não derruba a provisão (o provider já está ligada e o client-grade já foi gravado) — só loga WARN. O env não reinicia o app sozinho: aplica no próximo deploy (GET /deploy?uuid=…).

Configuração (env no recurso auth no Coolify)

Env Valor Secret
COOLIFY_API_URL base da API com /api/v1 (ex. http://coolify:8000/api/v1 interno, ou https://<host>/api/v1) não
COOLIFY_API_TOKEN token do Coolify (UI: Keys & Tokens → API tokens), escopo write (+ deploy se for disparar redeploy) sim

Verificação

Provisionar o glitchtip do próprio auth (dogfood) e conferir o env no recurso:

curl -s -X POST https://auth.xadm.biz/api/setup/provision \
  -H "Authorization: Bearer <JWT xadm_admin>" -H "Content-Type: application/json" \
  -d '{"app_id":"auth","feature":"glitchtip","grupo":"xadm","nome":"Auth","production_url":"https://auth.xadm.biz"}'

Depois, no painel do Coolify → recurso auth → Environment Variables: deve aparecer SENTRY_DSN (mascarado). Nos logs do auth: Coolify: 1 env(s) injetado(s) …. Recurso não encontrado → Coolify: recurso não encontrado p/ app=auth … (checar se o fqdn do recurso == production_url).

Limitações conhecidas

  • A API v4 não seta build-vs-runtime — o env entra com o default do Coolify (build+runtime).
  • production_url precisa bater com o fqdn do recurso; domínio múltiplo/alterado quebra o match (é o trade-off da descoberta por domínio, decisão 3.4b — a alternativa era uuid explícito).
  • O env é inerte até o app lê-lo. Injetar SENTRY_DSN no auth prova a entrega, mas o auth só reporta erro ao GlitchTip depois de instrumentado com um SDK (passo à parte).
  • A injeção é upsert, não substituição — casa por key, então renomear um env (como GLITCHTIP_DSN → SENTRY_DSN) não apaga o nome antigo: reprovisionar cria o novo e deixa o velho órfão no recurso. Remoção do órfão é manual, no painel.