SQLite (libSQL)
Um banco gerenciado é um serviço kind=database do projeto. Ele vive no nó de banco (outro host), não na rede privada do grupo: os apps o acessam pela URL com TLS. Escopo do token: databases:write (criar, apagar, rotacionar) e projects:read (ler). Veja Tokens e escopos.
1. Criar
Seção intitulada “1. Criar”name é o nome do serviço (^[a-z][a-z0-9-]{0,30}$, único no projeto; é o prefixo das referências ${{db.…}}). engine é postgres, mariadb ou sqlite; quota_mb é a cota em MB.
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\": \"demo-sq-$SUF\"}" | jq -r .id)
curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: sq-db-$SUF" \ -d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}'{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite", "status": "provisioning", "quota_mb": 1024}O banco nasce em provisioning e vira ready. Consulte GET /v1/projects/$P/databases/{s} com backoff (2 s, dobrando até 30 s, até uns 10 min) até o banco estar pronto antes de fazer deploy dos dependentes:
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\": \"demo-sq-$SUF\"}" | jq -r .id)DB=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: sq-db-$SUF" \ -d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}' | jq -r .id)
delay=2for i in $(seq 1 40); do st=$(curl -sS "$NEBULAR_API/v1/projects/$P/databases/$DB" -H "$H" | jq -r .status) echo "tentativa $i: $st" [ "$st" = ready ] && break sleep "$delay"; delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))donecurl -sS "$NEBULAR_API/v1/projects/$P/databases/$DB" -H "$H"{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite", "status": "ready", "quota_mb": 1024, "read_only": false}2. Variáveis entregues
Seção intitulada “2. Variáveis entregues”Todas sensíveis (mascaradas em log e UI) e referenciáveis por qualquer serviço do grupo:
| Variável | Conteúdo |
|---|---|
LIBSQL_URL |
libsql://… do banco |
LIBSQL_AUTH_TOKEN |
token de acesso (JWT) do banco |
DATABASE_URL |
igual a LIBSQL_URL |
A conexão é por TLS; o cliente libSQL usa LIBSQL_URL + LIBSQL_AUTH_TOKEN.
No app, use por referência (nunca copie o valor): ${{db.DATABASE_URL}}. Veja Conexão e referências.
Ler o valor em claro exige o escopo env:reveal num token criado com step-up (GET …/variables?resolved=true). Sem ele, o valor vem mascarado. As credenciais também saem de POST /v1/projects/{p}/databases/{s}/credentials (exige env:reveal): {"credentials": [{"name": "DATABASE_URL", "value": "..."}, ...]}.
3. Conectar de fora (diagnóstico)
Seção intitulada “3. Conectar de fora (diagnóstico)”Com as credenciais reveladas, use o SDK libSQL da sua linguagem com LIBSQL_URL e LIBSQL_AUTH_TOKEN (ilustrativo):
// SDK libSQL: createClient({ url: process.env.LIBSQL_URL, authToken: process.env.LIBSQL_AUTH_TOKEN })4. Cota
Seção intitulada “4. Cota”quota_mb é medida a cada 5 minutos. Acima do limite o banco vira read_only (escritas falham; há evento e aviso ao time) e volta ao normal ao baixar do limite (apague dados). O motor sinaliza quota_exceeded (422) quando a cota é incompatível com o uso.
Para mudar a cota: PATCH /v1/projects/{p}/databases/{s} com {"quota_mb": 2048} (databases:write); a resposta é o banco (quota_mb, size_mb, read_only). GET /v1/projects/{p}/databases lista os bancos do projeto.
5. Rotacionar credencial
Seção intitulada “5. Rotacionar credencial”POST /v1/projects/{p}/databases/{s}/rotate (databases:write) troca a chave de assinatura do banco: o LIBSQL_AUTH_TOKEN anterior passa a dar 401 na hora e um token novo é selado. A URL não muda. Os serviços dependentes são marcados “precisam de redeploy” (re-resolução): faça deploy deles.
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\": \"demo-sq-$SUF\"}" | jq -r .id)DB=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \ -H "Idempotency-Key: sq-db-$SUF" \ -d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}' | jq -r .id)
curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases/$DB/rotate" \ -H "$H"{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite"}6. Apagar
Seção intitulada “6. Apagar”DELETE /v1/projects/{p}/databases/{s} (databases:write; 204). Pela API de token a chamada não exige step-up (o painel exige); por padrão faz backup final antes ({"final_backup": false} no corpo desliga). Apagar é irreversível para os dados atuais; restaure do backup final se precisar (Backup e restore).
Se algo falhar
Seção intitulada “Se algo falhar”| Resposta | O que fazer |
|---|---|
401 / 403 |
Token ausente/sem escopo databases:write. Peça um token com o escopo. |
404 not_found |
Projeto ou banco inexistente ou de outro time (indistinguíveis). Confira os ids. |
409 name_taken |
Já existe um serviço com esse name no projeto (todo banco é um serviço). Use outro name. |
422 quota_exceeded |
Cota insuficiente para o uso atual. Apague dados ou peça cota maior. |
503 unavailable |
Nó de banco indisponível. Repita com backoff (a mesma Idempotency-Key). Persistindo, pare e avise uma pessoa. |
429 rate_limited |
Espere Retry-After. |
Tabela completa: Erros.