# Aplicações

URL: https://0.0.0.0:3002/docs/aplicacoes

Tipos, origens do código, endereço em acq.lat, deploy, variáveis de ambiente, domínios e backups.

Uma **aplicação** roda dentro de um workspace e usa a memória do [plano](/docs/planos-e-quotas). A CPU vem da memória: 1 vCPU garantida por GB e, nos picos, a CPU livre do workspace até a vCPU do plano.

| Tipo       | Para quê                                                                    | Endereço                                             |
| ---------- | --------------------------------------------------------------------------- | ---------------------------------------------------- |
| **Web**    | Sites e APIs: a app escuta numa porta (padrão `3000`, disponível em `PORT`) | `https://<subdomínio>.acq.lat`, com HTTPS automático |
| **Worker** | Processos sem porta: bots, filas, tarefas                                   | Nenhum                                               |

O código vem de uma de três **origens**, escolhidas na criação:

* **Upload de .zip:** você envia o código e o Hydro faz o build, detectando a linguagem.
* **Imagem Docker:** uma imagem pública (ex.: `ghcr.io/empresa/bot:1.2.0`), sem build.
* **GitHub:** um repositório conectado, com build no Hydro. Veja [Deploy pelo GitHub](/docs/deploy-github).

## Criar [#criar]

`POST /v1/workspaces/{id}/apps` com nome, tipo, origem e memória (`memoryMb`, qualquer inteiro a partir de 100 MB). A vCPU (`cpuMillis` na resposta) é calculada pela memória.

* O identificador sai do nome (`Minha API` → `minha-api`) e pode ser informado em `slug`. Ele é único no workspace.
* O tamanho é **reservado no plano na hora**: se não couber, a resposta é `409 quota_exceeded`. Mínimo de 100 MB por aplicação.
* Sem plano em vigor, a resposta é `403 plan_required`.
* Criar não sobe nada: o código chega no primeiro deploy.

## Endereço em acq.lat [#endereço-em-acqlat]

Toda aplicação web ganha um endereço `https://<subdomínio>.acq.lat` com HTTPS.

* **Escolha o subdomínio** na criação, em `subdomain` (ex.: `minha-loja` → `minha-loja.acq.lat`). Sem ele, o Hydro gera um a partir do identificador, com um sufixo.
* Regras: 3 a 40 caracteres, letras minúsculas, números e hífens, sem hífen no começo, no fim ou repetido. Alguns nomes são reservados.
* O subdomínio é **único em toda a plataforma**: se já estiver em uso, a resposta é `409 subdomain_taken`.
* **Trocar depois:** em **Configurações → Endereço**, ou `PATCH .../apps/{appId}` com `subdomain`. O endereço novo vale na hora e o antigo **para de responder**.

## Deploy [#deploy]

| Origem           | Como                                                                                                                   |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Upload de .zip   | `POST .../apps/{appId}/deployments/upload` com o arquivo no corpo (`Content-Type: application/zip`, até 200 MB)        |
| Imagem Docker    | `POST .../apps/{appId}/deployments` com `{ "image": "..." }` (ou vazio para usar a imagem da app). Só imagens públicas |
| Refazer o deploy | `POST .../apps/{appId}/deployments` vazio numa app por upload: reaproveita o build atual com variáveis e tamanho novos |

* **O que vai no .zip:** só o código. A pasta `node_modules` não é aceita (`400 artifact_has_node_modules`): as dependências são instaladas no build. O .zip também é recusado (`422 artifact_invalid`) com caminhos absolutos ou com `..`, mais de 50 mil entradas, mais de 2 GB descompactados ou compressão suspeita.
* Só **um deploy em andamento** por aplicação (`409 deployment_in_progress`). Um deploy na fila pode ser cancelado (`POST .../deployments/{id}/cancel`).
* Estados: na fila → fazendo build → subindo → no ar. Se falhar, o deploy anterior continua no ar e o motivo aparece em `failureReason`.
* **Logs de build:** `GET .../deployments/{id}/logs?after=0`; leia de novo com `after = nextAfter` até `done`. Cada deploy guarda até 5 MB de log.
* **Rollback:** `POST .../deployments/{id}/rollback` sobe de novo a imagem de um deploy anterior, sem build, enquanto ela estiver disponível (`imageAvailable`). As 3 últimas imagens de cada app ficam guardadas.

## O que a aplicação encontra [#o-que-a-aplicação-encontra]

* **Web:** escute em `0.0.0.0` na porta da variável `PORT`. O deploy só entra no ar quando a porta responde (até 60 s); se não responder, o deploy falha e a versão anterior continua.
* **Pasta do projeto:** gravável e persistente. O que a aplicação grava ali, como um banco SQLite ou uploads, continua entre deploys e reinícios e entra nos backups. `/tmp` serve para temporários (64 MB).
* **Usuário:** a aplicação roda como usuário sem privilégios, dono da pasta do projeto.
* **Variáveis do Hydro:** `PORT` (web), `HYDRO_APP_ID` e `HYDRO_DEPLOYMENT_ID`.
* **Troca sem queda (web):** a versão nova sobe ao lado da antiga e o endereço só muda quando ela responde. Workers param a versão antiga antes de subir a nova, para nunca rodarem dois ao mesmo tempo.
* **Rede:** aplicações e bancos do mesmo workspace ficam numa rede privada; os de outros workspaces não os alcançam. Cada um tem um nome interno, como `minha-api.internal`. A saída para a internet é liberada.

## Variáveis de ambiente [#variáveis-de-ambiente]

`PUT /v1/workspaces/{id}/apps/{appId}/env` substitui o conjunto inteiro (até 100 variáveis, 32 KB por valor).

* Marque como **segredo** o que não deve aparecer de volta: a API e o painel nunca mostram o valor de um segredo (`value: null`). Para manter um segredo sem reenviar o valor, mande-o com valor vazio.
* Tudo é guardado **cifrado** (AES-256-GCM) e nunca entra no build.
* `PORT` e nomes começando com `HYDRO_` são reservados.
* Mudanças valem a partir do próximo deploy (refazer o deploy aplica sem novo build).

## Parar, iniciar e reiniciar [#parar-iniciar-e-reiniciar]

`POST .../apps/{appId}/stop`, `.../start` e `.../restart` (exigem um deploy no ar: `409 app_not_deployed`). Parar tira a app e o endereço do ar, mas mantém o tamanho reservado e a pasta do projeto.

## Estado [#estado]

O `status` vem do servidor em que a app roda: `idle` (sem deploy), `deploying`, `starting`, `running`, `restarting`, `stopped` ou `crashed`. Em `statusDetail` ficam o código de saída, o número de reinícios e as últimas linhas quando o processo cai.

* Se o processo cai, ele é reiniciado automaticamente, com espera crescente.
* Depois de 5 saídas em 10 minutos, a app fica `crashed` e é parada, para não ficar em loop.

## Domínios personalizados [#domínios-personalizados]

Apps web podem responder também num domínio seu, com HTTPS automático.

1. Em **Configurações → Endereço**, adicione o domínio (ex.: `loja.exemplo.com.br`). Até 20 por aplicação.
2. No DNS do domínio, crie um registro **A** para o IP mostrado no painel (e **AAAA**, se houver IPv6) e um **TXT** `_hydro.<domínio>` com o valor indicado.
3. Clique em **Verificar**. Com A e TXT certos, o domínio fica **Ativo** e o certificado é emitido em seguida.

* O registro A precisa apontar direto para o IP indicado. Um proxy na frente (como o da Cloudflare com a nuvem laranja) impede a emissão do certificado.
* O IP é o mesmo para todos os domínios e não muda se a aplicação trocar de servidor.
* Enquanto o domínio aponta para o Hydro sem estar ligado a uma aplicação, ele mostra a página "Domínio ainda não conectado".
* O Hydro rechecha sozinho domínios **Aguardando DNS** por até 7 dias e os ativos a cada 6 horas.
* Um domínio só pode estar em uma aplicação da plataforma (`409 domain_taken`).

| Método        | Caminho                                    |
| ------------- | ------------------------------------------ |
| `GET`, `POST` | `/v1/workspaces/{id}/apps/{appId}/domains` |
| `POST`        | `…/domains/{domainId}/verify`              |
| `DELETE`      | `…/domains/{domainId}`                     |

## Backups dos arquivos [#backups-dos-arquivos]

A pasta do projeto tem backup diário automático, cifrado e fora do servidor. Em **Configurações → Backups**: fazer backup agora (no máximo um por hora) e restaurar, o que substitui a pasta do projeto pela do backup. Antes de restaurar, o Hydro guarda um backup do estado atual.

## Excluir [#excluir]

`DELETE /v1/workspaces/{id}/apps/{appId}` libera o tamanho no plano e remove a aplicação, as imagens e a pasta do projeto.

## Permissões [#permissões]

| Ação                                                      | Papéis                                     |
| --------------------------------------------------------- | ------------------------------------------ |
| Ver aplicações, deploys e variáveis (segredos mascarados) | Todos, inclusive leitor                    |
| Criar, alterar, fazer deploy, excluir                     | Desenvolvedor, administrador, proprietário |
