# Bancos de dados

URL: https://0.0.0.0:3002/docs/bancos-de-dados

PostgreSQL, MySQL, Redis e MongoDB gerenciados, na rede privada do workspace e com acesso externo opcional.

O Hydro cria e mantém bancos de dados ao lado das suas aplicações. Cada banco roda isolado, com volume próprio, e só é acessível pela **rede privada do workspace**, a menos que você ligue o acesso externo.

| Motor      | Versões    | Porta | Variável ao conectar |
| ---------- | ---------- | ----- | -------------------- |
| PostgreSQL | 18, 17, 16 | 5432  | `DATABASE_URL`       |
| MySQL      | 8.4        | 3306  | `DATABASE_URL`       |
| Redis      | 8, 7.4     | 6379  | `REDIS_URL`          |
| MongoDB    | 8, 7       | 27017 | `MONGODB_URL`        |

## Criar [#criar]

`POST /v1/workspaces/{id}/databases` com nome, motor, versão e memória (`memoryMb`). No painel: **Bancos de dados → Criar banco**.

* A memória sai da quota do plano. A vCPU vem da memória (1 vCPU garantida por GB) e, nos picos, o banco divide a vCPU do plano com as apps. O disco não conta na quota.
* A memória é qualquer número inteiro de MB a partir do mínimo do motor: PostgreSQL 256 MB, MySQL e MongoDB 512 MB, Redis 64 MB.
* Mudar o tamanho (`PATCH`) reinicia o banco; os dados ficam no volume.

## Rede privada [#rede-privada]

* Cada banco e cada aplicação têm um nome na rede do workspace: `<identificador>` e `<identificador>.internal`. Ex.: `postgres://hydro:…@meu-banco.internal:5432/hydro`.
* Os nomes são únicos no workspace entre apps e bancos (`409 name_taken`).
* Bancos e apps de outros workspaces não resolvem nem conectam.

## Credenciais [#credenciais]

* Usuário e banco padrão: `hydro`. A senha é gerada pelo Hydro e guardada cifrada.
* `GET …/credentials` devolve host, porta, usuário, banco e a URL de conexão. Cada consulta fica registrada na atividade do workspace.
* **Trocar a senha** (`POST …/rotate-password`) aplica uma senha nova sem perder dados. Apps conectadas precisam ser conectadas de novo e reiniciadas.

## Conectar a uma aplicação [#conectar-a-uma-aplicação]

`POST …/connect` com `{ appId, variable? }` grava a URL de conexão interna como **variável secreta** da app (a padrão da tabela acima, ou outro nome). Vale no próximo deploy ou reinício da app.

## Acesso externo [#acesso-externo]

Desligado por padrão. Ao ligar (`PUT …/public` com `{ enabled: true, allowedCidrs }`):

* **Qualquer IP:** deixe `allowedCidrs` vazio. Conecta de qualquer lugar, com a senha do banco.
* **Só IPs específicos (mais seguro):** informe as faixas, como `["203.0.113.10/32", "198.51.100.0/24"]`. Só elas conectam.
* O banco ganha uma porta própria no IP público do servidor.
* A conexão é **sempre com TLS**. O certificado é autoassinado: use `sslmode=require` (PostgreSQL), `ssl-mode=REQUIRED` (MySQL), `rediss://` (Redis) ou `tls=true&tlsAllowInvalidCertificates=true` (MongoDB). Conexões sem TLS são recusadas.

A URL externa aparece nas credenciais quando o acesso está ligado.

## Backups [#backups]

Cada banco tem backup **diário automático**, guardado fora do servidor e cifrado. Na aba **Backups**:

* **Fazer backup agora:** um backup manual, no máximo um por hora.
* **Restaurar em um banco novo:** cria outro banco com os dados do backup. O original fica intacto.
* **Restaurar neste banco:** substitui os dados atuais pelos do backup. Antes, o Hydro faz um backup do estado atual; se ele falhar, nada é restaurado.

Guardamos os 7 diários mais recentes, os manuais por 30 dias e os feitos antes de uma restauração por 7 dias. Ao excluir o banco, os backups ainda ficam 7 dias. O espaço dos backups não conta no plano.

## Logs e consumo [#logs-e-consumo]

Logs e consumo ao vivo funcionam como nas aplicações (veja [Logs, métricas, terminal e arquivos](/docs/aplicacoes-runtime)). Bancos não têm terminal nem aba de arquivos.

## API [#api]

| Método                   | Caminho                                                   |
| ------------------------ | --------------------------------------------------------- |
| `GET`, `POST`            | `/v1/workspaces/{id}/databases`                           |
| `GET`, `PATCH`, `DELETE` | `/v1/workspaces/{id}/databases/{databaseId}`              |
| `POST`                   | `…/{databaseId}/start`, `stop`, `restart`                 |
| `GET`                    | `…/{databaseId}/credentials`                              |
| `POST`                   | `…/{databaseId}/rotate-password`                          |
| `POST`                   | `…/{databaseId}/connect` com `{ appId, variable? }`       |
| `PUT`                    | `…/{databaseId}/public` com `{ enabled, allowedCidrs }`   |
| `GET`, `POST`            | `…/{databaseId}/backups` e `…/backups/{backupId}/restore` |

Erros específicos: `name_taken`, `workspace_node_full` (sem espaço para o banco), `database_not_ready` (banco ainda sendo criado, ou parado ao trocar a senha) e `public_port_exhausted`.
