# Conexão e referências

O banco **não** entra na rede privada do grupo (`nbg-…`): ele fica no nó de banco e é acessado pela URL das variáveis, com TLS, no `public_host`. Por isso o app deve usar as variáveis entregues, nunca um hostname montado à mão.

## Variáveis referenciáveis

Prefixo = `name` do serviço-banco (aqui `db`):

| Motor | Referências |
|---|---|
| PostgreSQL | `${{db.DATABASE_URL}}`, `${{db.PGHOST}}`, `${{db.PGPORT}}`, `${{db.PGUSER}}`, `${{db.PGPASSWORD}}`, `${{db.PGDATABASE}}` |
| MariaDB | `${{db.DATABASE_URL}}`, `${{db.MYSQL_HOST}}`, `${{db.MYSQL_PORT}}`, `${{db.MYSQL_USER}}`, `${{db.MYSQL_PASSWORD}}`, `${{db.MYSQL_DATABASE}}` |
| SQLite | `${{db.LIBSQL_URL}}`, `${{db.LIBSQL_AUTH_TOKEN}}`, `${{db.DATABASE_URL}}` |

Todas são sensíveis: o valor resolvido de quem as referencia herda a sensibilidade e fica mascarado em log e UI (veja [Referência a valor sensível](/conectados/variaveis-e-referencias/#referência-a-valor-sensível)).

## Ligar o app ao banco

Defina no serviço do app uma variável cujo valor é a referência. A resolução acontece no **deploy**.

```bash
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" \
  -H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \
  -H "Idempotency-Key: conexao-proj-$(date +%s)-$RANDOM" \
  -d "{\"name\": \"demo-conexao-$(date +%s)-$RANDOM\"}" | 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: conexao-svc-$P" \
  -d '{"name": "api", "kind": "app", "visibility": "private", "source": {"type": "image", "ref": "ghcr.io/org/app:1.2"}}' | jq -r '.id')

curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/DATABASE_URL" \
  -H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \
  -d '{"value": "${{db.DATABASE_URL}}"}'
```
```json
{"name": "DATABASE_URL"}
```

O `POST` do deploy responde `422 unresolved_reference` se `db` não existir no projeto ou a variável não existir (`details.references` lista quais), e `422 reference_cycle` se as referências formarem ciclo. Corrija a referência e faça deploy de novo; não adianta repetir igual.

## Conexão com TLS

- PostgreSQL: mantenha `sslmode=verify-full` (já vem na `DATABASE_URL`); a CA é pública, não instale nada.
- MariaDB: `ssl=true` (já vem na `DATABASE_URL`).
- SQLite: `LIBSQL_URL` (TLS) + `LIBSQL_AUTH_TOKEN`.

## Como o serviço alcança o banco

O serviço conecta ao `public_host` do nó de banco (por exemplo `db1.<dominio>:5432`), saindo da rede do projeto pela internet pública, **sempre com TLS** (`sslmode=verify-full` no PostgreSQL: valide o certificado e o nome do host, com a CA pública, sem instalar nada). O nó de banco só aceita conexões vindas dos **IPs de saída da plataforma**: um cliente em outra origem (seu notebook, outro provedor) é recusado na rede, mesmo com a credencial certa. Cada banco tem a **sua própria credencial** (usuário e senha só dele, sem privilégios administrativos), entregue pelas referências acima. O acesso direto de fora da plataforma não é suportado: faça a consulta de dentro de um serviço do projeto. Detalhes de isolamento: [Isolamento](/seguranca/isolamento/#bancos-gerenciados).

## Quando o valor muda

Rotação de credencial, restore em SQLite ou restore para banco novo mudam o valor referenciado: os serviços dependentes ficam marcados "precisam de redeploy". Faça deploy deles ([Deploys e status](/operacao/deploys-e-status/)).

## Se algo falhar

| Resposta | O que fazer |
|---|---|
| `422 unresolved_reference` no deploy | Variável ou serviço referenciado não existe: confira o nome do serviço-banco e a variável da tabela acima. |
| `422 reference_cycle` no deploy | Remova a referência circular entre variáveis. |
| app não conecta (TLS/credencial) | Houve rotação? Faça deploy do app para re-resolver. |
| `404 not_found` | Projeto/serviço inexistente ou de outro time. |

Veja [Variáveis e referências](/conectados/variaveis-e-referencias/) e [Erros](/erros/tabela/).

Se um app usa um driver de banco (PostgreSQL, MySQL, MongoDB) mas nenhum banco está ligado, a plataforma detecta e **sugere** criar um banco gerenciado e injetar a referência `${{db.DATABASE_URL}}` automaticamente — sem criar nada sem a sua autorização. Veja [Sugestões de persistência](/conectados/sugestoes-de-persistencia/).
