Variáveis e referências
Escopos: env:read, env:write, env:reveal (Tokens e escopos).
Escopos de variável
Seção intitulada “Escopos de variável”service: vale só para um serviço. Rota:/v1/projects/{p}/services/{s}/variables[/{name}].shared: guardada no projeto. Rota:/v1/projects/{p}/shared-variables[/{name}]. Ela não entra sozinha no ambiente de nenhum serviço: só chega a um serviço que a referencie com${{shared.NOME}}(veja abaixo).
Valor literal ou com referências: ${{<servico>.<VAR>}} (variável de outro serviço do projeto) e ${{shared.VAR}} (variável compartilhada). shared é nome reservado: nenhum serviço pode se chamar assim.
Definir, ler e apagar
Seção intitulada “Definir, ler e apagar”SUF=$(date +%s)-$RANDOMP=$(curl -sS -X POST "$NEBULAR_API/v1/projects" \ -H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \ -H "Idempotency-Key: var-proj-$SUF" -d "{\"name\": \"vars-$SUF\"}" | jq -r .id)S=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" \ -H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \ -H "Idempotency-Key: var-svc-$SUF" \ -d "{\"name\": \"api\", \"kind\": \"app\", \"visibility\": \"private\", \"source\": {\"type\": \"image\", \"ref\": \"ghcr.io/org/api:1.0\"}}" | jq -r .id)curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" \ -H "Authorization: Bearer $NEBULAR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"value": "info"}'{"name": "LOG_LEVEL", "value": "info", "sensitive": false, "needs_redeploy": []}O corpo do PUT é {"value": "...", "sensitive": true|false} (sensitive é opcional; uma variável já sensível nunca volta a ser não sensível). A resposta traz a variável e needs_redeploy, a lista de serviços que precisam de novo deploy para ver o valor (vazia quando nenhum serviço usa a variável). Variável sensível: o PUT nunca devolve o valor ("value": null) e as leituras só o mostram a um token com env:reveal; sem ele, value vem null e sensitive vem true.
Para definir várias de uma vez (tudo ou nada, de 1 a 200 itens), use PUT .../variables com {"variables": [{"name": "A", "value": "1"}, {"name": "B", "value": "2", "sensitive": true}]}; a resposta é {"items": [...], "needs_redeploy": [...]}. GET .../variables?resolved=true devolve as variáveis já com as referências expandidas e as automáticas (exige env:reveal).
Variável compartilhada do projeto:
SUF=$(date +%s)-$RANDOMP=$(curl -sS -X POST "$NEBULAR_API/v1/projects" \ -H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \ -H "Idempotency-Key: var2-proj-$SUF" -d "{\"name\": \"vars2-$SUF\"}" | jq -r .id)curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/shared-variables/REGION" \ -H "Authorization: Bearer $NEBULAR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"value": "br"}'Para que o serviço enxergue a variável compartilhada REGION, crie nele uma variável própria que a referencie (o nome pode ser o mesmo ou outro). Sem essa referência, REGION não aparece no ambiente do serviço:
PUT /v1/projects/{p}/services/{s}/variables/REGION{"value": "${{shared.REGION}}"}Referência a outro serviço (o front lê a URL privada do back):
SUF=$(date +%s)-$RANDOMH="Authorization: Bearer $NEBULAR_TOKEN"P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: var3-proj-$SUF" -d "{\"name\": \"vars3-$SUF\"}" | jq -r .id)curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" -H "$H" -H "Content-Type: application/json" \ -d '{"name": "api", "kind": "app", "visibility": "private", "port": 8080, "source": {"type": "image", "ref": "ghcr.io/org/api:1.0"}}' >/dev/nullS=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \ -d "{\"visibility\": \"public\", \"slug\": \"vars3-$SUF\", \"source\": {\"type\": \"image\", \"ref\": \"ghcr.io/org/web:1.0\"}}" | jq -r .id)curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/API_URL" -H "$H" \ -H "Content-Type: application/json" -d '{"value": "${{api.PRIVATE_URL}}"}'Listar (valores sensíveis vêm mascarados sem env:reveal) e apagar:
SUF=$(date +%s)-$RANDOMH="Authorization: Bearer $NEBULAR_TOKEN"P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: var4-proj-$SUF" -d "{\"name\": \"var4-$SUF\"}" | jq -r .id)S=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: var4-svc-$SUF" \ -d '{"name": "app", "kind": "app", "visibility": "private", "source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H" \ -H "Content-Type: application/json" -d '{"value": "info"}'curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/variables" -H "$H"curl -sS -X DELETE "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H"Variáveis automáticas (resolvíveis por referência)
Seção intitulada “Variáveis automáticas (resolvíveis por referência)”Todo serviço ganha, sem você definir:
| Variável | Valor |
|---|---|
NEBULAR_SERVICE_NAME |
o name do serviço |
PORT |
a porta interna |
PRIVATE_HOST |
<name> (hostname na rede privada) |
PRIVATE_URL |
http://<name>:<port> |
PUBLIC_URL |
URL pública, se o serviço é public; senão vazio |
PUBLIC_DOMAIN |
domínio público do serviço |
Serviços de banco também expõem DATABASE_URL e as variáveis do motor (Conexão e referências). Exemplo: ${{api.PRIVATE_URL}}, ${{db.DATABASE_URL}}.
Se um app precisa de um banco ou de disco persistente que ainda não existe, a plataforma detecta e sugere criar o recurso (e, no caso de banco, injetar a referência ${{db.DATABASE_URL}}), sempre esperando sua autorização: veja Sugestões de persistência.
Como a resolução funciona
Seção intitulada “Como a resolução funciona”- Acontece no deploy, por serviço. Quem é referenciado sobe antes (ordem topológica no deploy de grupo).
- Referência a variável ou serviço inexistente: o
POSTdo deploy responde422 unresolved_referencee nada é criado;details.referenceslista os nomes com problema. OPUTda variável aceita a referência: o erro só aparece no deploy. - Referências em ciclo:
422 reference_cycle(também comdetails.references). - Outros erros de resolução presentes na API:
invalid_reference(um${{...}}que não é da formaescopo.VAR),reference_too_deep(aninhamento acima de 16 níveis) evalue_too_large(valor expandido acima de 64 KiB ou ambiente acima de 256 KiB). - Valor resolvido herda a sensibilidade do que foi referenciado (veja a próxima seção).
- Re-resolução: mudar um valor referenciado marca os dependentes como “precisam de redeploy”. Faça um novo deploy dos dependentes (ou ative
auto_deploy).
Referência a valor sensível
Seção intitulada “Referência a valor sensível”Uma variável cujo valor é uma referência (DATABASE_URL = ${{db.DATABASE_URL}}) guarda o texto da referência, não o segredo. Por isso:
- O
PUTpode responder"sensitive": falsee a leitura semresolvedmostra o texto${{db.DATABASE_URL}}: nada de segredo trafega ali. Se quiser a variável tratada como sensível já na definição, envie"sensitive": truenoPUT(a resposta volta comvalue: null). - O valor resolvido herda a sensibilidade de quem foi referenciado:
GET ...?resolved=truemostraDATABASE_URLcom"sensitive": true, e o valor fica mascarado em log e painel. - Essa leitura resolvida (e
env:revealem geral) entrega o segredo em claro ao token com o escopoenv:reveal, que precisa ser pedido explicitamente ao criar o token (Tokens e escopos). Sem o escopo,resolved=truedá403. Trate a resposta como segredo: não a registre em log nem a cole em chat. depends_ondo serviço (usado para a ordem do deploy de grupo) é calculado das referências gravadas: o serviçoapipassa a listar["db"]na leitura do serviço assim que a variável com${{db...}}existe. A resposta de criação do serviço, anterior à variável, vem comdepends_onvazio.
Ler valores resolvidos
Seção intitulada “Ler valores resolvidos”GET .../variables?resolved=true devolve os valores já expandidos. Exige o escopo env:reveal (token criado com step-up) e devolve valores sensíveis em claro.
SUF=$(date +%s)-$RANDOMH="Authorization: Bearer $NEBULAR_TOKEN"P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \ -d "{\"name\": \"var5-$SUF\"}" | jq -r .id)S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \ -d '{"source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H" \ -H "Content-Type: application/json" -d '{"value": "info"}' >/dev/null
curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/variables?resolved=true" \ -H "$H"{"items": [{"name": "LOG_LEVEL", "value": "info", "sensitive": false}], "next_cursor": null, "has_more": false}Se algo falhar
Seção intitulada “Se algo falhar”| Resposta | O que fazer |
|---|---|
403 forbidden |
Falta env:write (escrever), env:read (ler) ou env:reveal (resolved=true). Peça token novo. |
404 not_found |
Projeto, serviço ou variável inexistente ou fora do seu acesso. |
422 unresolved_reference no deploy |
Crie a variável/serviço citado ou corrija o nome na referência; redeploy. |
422 reference_cycle no deploy |
Quebre o ciclo (A referencia B que referencia A). |
400 invalid_request |
Nome ou valor inválido: corrija. |