# Deploys e status

Escopos: `deploy` (disparar), `projects:read` (consultar).

## Estados

| Estado | Significado | O agent deve |
|---|---|---|
| `queued` | na fila | esperar |
| `building` | construindo | esperar |
| `deploying` | subindo o container | esperar |
| `ready` | no ar | terminar com sucesso |
| `failed` | build ou subida falhou | ler o [log de build](/operacao/logs/) e corrigir; não repetir igual |
| `blocked` | um serviço do qual este depende falhou no deploy de grupo | corrigir o dependente primeiro |
| `canceled` | cancelado | decidir se dispara de novo |
| `superseded` | um deploy mais novo tomou o lugar | acompanhar o mais novo |

## Disparar

- Serviço: `POST /v1/projects/{p}/services/{s}/deployments` (git ref, imagem ou upload multipart). Veja [Primeiro deploy](/comecar/primeiro-deploy/).
- Grupo: `POST /v1/projects/{p}/deploy` (corpo `{}` com `Content-Type: application/json`, ou sem corpo). Ordem topológica das referências entre serviços: quem é referenciado sobe antes. Se o build de um serviço falhar, os dependentes ficam `blocked`; os serviços já ativos permanecem. Serviço `upload` que já recebeu arquivo é reimplantado com o último arquivo; sem nenhum arquivo (sem fonte), o item vem `skipped` com `reason` e o grupo segue ([Front, back e banco](/conectados/front-back-db/#5-deploy-do-grupo)).

## Consultar e listar

```bash
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
  -H "Idempotency-Key: dep-proj-$SUF" -d "{\"name\": \"dep-$SUF\"}" | jq -r .id)
S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \
  -d '{"visibility": "private", "source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)
curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/deployments" -H "$H"
```
```json
{"items": [], "next_cursor": null, "has_more": false}
```

A lista usa cursor (`next_cursor`, `has_more`): siga enquanto `has_more` for `true`.

## Polling com backoff

Não há webhooks neste ciclo. Consulte `GET .../deployments/{d}`: comece em 2 s, dobre a cada tentativa até 30 s, no máximo cerca de 10 minutos (40 tentativas). Pare em qualquer estado terminal.

```bash
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
  -d "{\"name\": \"dep2-$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)
D=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services/$S/deployments" -H "$H" \
  -H "Content-Type: application/json" -d '{}' | jq -r .id)

delay=2
for i in $(seq 1 40); do
  st=$(curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/deployments/$D" -H "$H" | jq -r .status)
  echo "tentativa $i: $st"
  case "$st" in
    ready) break ;;
    failed|blocked|canceled|superseded) echo "deploy terminou em $st" >&2; exit 1 ;;
  esac
  sleep "$delay"; delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))
done
[ "$st" = ready ]
```

**Deploy de grupo**: faça polling no grupo, não serviço a serviço: `GET /v1/projects/{p}/group-deployments/{g}` (`g` é o `id` devolvido pelo `POST .../deploy`). O `status` do grupo é `running` até terminar e então `ready`, `failed`, `canceled` ou `superseded`; cada item tem seu `status` (inclui `blocked` e `skipped`). Mesmo backoff.

Em `429`, espere o `Retry-After` antes da próxima consulta ([Rate limit e retry](/erros/rate-limit-e-retry/)).

## Auto-deploy por git

Com `auto_deploy: true` e `source.type = "git"`, o push no branch dispara deploy. O webhook encontra **todos** os serviços ligados àquele repositório e branch. Com `watch_paths` (ex.: `["apps/api/**"]`) só os serviços afetados são reimplantados; se vários serviços do mesmo projeto forem afetados, vira um deploy de grupo. Veja [Monorepo](/guia/monorepo/).

## Se algo falhar

| Resposta | O que fazer |
|---|---|
| `404 not_found` | Deploy, serviço ou projeto inexistente ou fora do seu acesso. |
| deploy `failed` | Leia o [log de build](/operacao/logs/). Se a imagem exige root, o container não sobe: use uma imagem que rode como não-root. |
| deploy `blocked` | Corrija o serviço dependente que falhou e dispare o grupo de novo. |
| `unresolved_reference` / `reference_cycle` | [Variáveis e referências](/conectados/variaveis-e-referencias/). |
| `409 deploy_in_progress` | Já há um deploy em andamento para o recurso; acompanhe-o. |
