Banco de dados do deploy (Postgres / SQL Server)
Esta página é o playbook prático para dar um banco a um deploy/tenant. Para a arquitetura dual-engine (Prisma, migrations, imagens) veja Bancos Suportados; para o fluxo completo do tenant veja Adicionar um novo tenant.
O app sempre alcança o banco por host.docker.internal:<porta>, e os
scripts db-postgres.sh / db-sqlserver.sh leem o MESMO .env que o app.
Então você define as variáveis DB_* uma vez no .env.<grupo>, e o
container do banco já sobe casado com elas — sem ficar acertando à mão.
O banco roda no seu próprio projeto compose (h1-db-postgres /
h1-db-sqlserver), separado do app (h1-stack). Ele pode até estar em outra
máquina — o app só precisa da URL/porta certa no .env.
Escolha seu caminho
Você já tem um banco pronto (Postgres no host, ou SQL Server gerenciado/externo)?
├─ SIM → Caminho A (só apontar o .env) → vá para §A
└─ NÃO, quero subir um container com nossos scripts:
├─ Postgres → Caminho B-PG → vá para §B
└─ SQL Server → Caminho B-MS → vá para §B
Quer DB + app num comando só? → Caminho C → vá para §C
Todos os caminhos terminam no mesmo lugar: §Deploy (subir o app) e §Verificar.
Variáveis de conexão — defina uma vez no .env.<grupo>
Postgres (padrão):
DB_ENGINE=postgres # (default; pode omitir)
POSTGRES_HOST=host.docker.internal
POSTGRES_HOST_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<senha>
HSBR_DB_NAME=ga6
SQL Server:
DB_ENGINE=sqlserver
DB_MSSQL_HOST=host.docker.internal
DB_MSSQL_PORT=1433
DB_MSSQL_USER=sa
DB_MSSQL_SA_PASSWORD=<senha forte>
DB_MSSQL_ENCRYPT=true
DB_MSSQL_TRUST_CERT=true
HSBR_DB_NAME=ga6
Num tenant comercial (COMPOSE_PROFILES=hsbr) o license server não roda
neste host — o back fala com ele por HTTP (LICENSE_SERVER_URL). Então o
único banco que você provisiona é o do H1 Tech (Postgres ou SQL Server). O
banco h1_license só importa no host que roda o profile license/all.
§A — Banco já existe (host ou gerenciado/externo)
Use quando há um Postgres já no host, ou um SQL Server gerenciado (Azure SQL, RDS, um servidor da casa do cliente, etc.).
- Aponte o
.env.<grupo>para ele (host/porta/usuário/senha — tabela acima). Para banco em outra máquina, troquehost.docker.internalpelo host real (ex.:sqlserver.cliente.localou o IP/DNS gerenciado). - Garanta que o banco do H1 Tech existe (o app não cria o database):
- Postgres:
createdb ga6(ouCREATE DATABASE ga6;). - SQL Server:
CREATE DATABASE [ga6];. - (As tabelas são criadas pelo
migrate deployno boot — você só precisa do database vazio.)
- Postgres:
- Pule para §Deploy. (Não rode
db-*.sh— você não quer um container; já tem banco.)
§B — Subir um container de banco com nossos scripts (split)
Sobe o banco primeiro, no projeto dele, e depois o app. Rode em
DevOps/docker/.
Os dois scripts publicam o container no gateway da bridge docker (ex.:
172.17.0.1), não em loopback — é por esse IP que os containers do app
resolvem host.docker.internal; um publish em 127.0.0.1 seria invisível
para eles (ver Troubleshooting). E ao final eles testam o
alcance a partir de um container: se o firewall bloquear, o script morre
imprimindo a regra UFW exata, antes do deploy entrar em loop de erro.
B-PG · Postgres
./scripts/db-postgres.sh --env <grupo>
Sobe postgres:16-alpine (projeto h1-db-postgres) em
<gateway>:${POSTGRES_HOST_PORT}, com volume h1-pgdata, e no 1º boot cria
h1_license + ga6 (via init-dbs.sql). Lê POSTGRES_PASSWORD /
POSTGRES_USER / POSTGRES_HOST_PORT / DB_PUBLISH_BIND do .env.
B-MS · SQL Server
Garanta os DB_MSSQL_* no .env (tabela acima), então:
./scripts/db-sqlserver.sh --env <grupo>
Sobe mcr.microsoft.com/mssql/server:2019-latest (projeto h1-db-sqlserver)
em <gateway>:${DB_MSSQL_PORT}, com volume h1-mssqldata, espera ficar
saudável e cria HSBR_DB_NAME (SQL Server não auto-cria database, então um
passo db-init roda o CREATE DATABASE). Lê DB_MSSQL_SA_PASSWORD /
DB_MSSQL_PORT / HSBR_DB_NAME / DB_PUBLISH_BIND do .env.
Confira com ss -ltnp | grep 1433. Se sim, não brigue pela porta: use
DB_MSSQL_PORT=14333 no .env — essa única variável controla o publish do
container e a conexão do app, então os dois ficam casados automaticamente.
Quando o script retorna (probe ✔), o banco está pronto, saudável e alcançável pelos containers. Vá para §Deploy.
§C — Tudo de uma vez
Não existe um único compose que suba banco e app juntos (são projetos separados de propósito — o banco costuma ser externo). Mas você pode encadear num comando:
# Postgres
./scripts/db-postgres.sh --env <grupo> && ./scripts/deploy-stack.sh <grupo>
# SQL Server
./scripts/db-sqlserver.sh --env <grupo> && ./scripts/deploy-stack.sh <grupo>
O && garante a ordem: o banco fica saudável (os scripts usam --wait) antes
do app rodar as migrations. É o caminho §B + §Deploy numa linha.
§Deploy — subir o app (comum a todos os caminhos)
./scripts/deploy-stack.sh <grupo> # == deploy.sh --env <grupo>
O deploy-stack.sh lê o engine do .env. Se DB_ENGINE=sqlserver, ele
layer-a docker-compose.sqlserver.yml automaticamente (imagem
…-sqlserver, conexão DB_MSSQL_*, hub desligado). O entrypoint roda
prisma migrate deploy (e seed, se HSBR_RUN_SEED=1) no banco que você proveu.
-sqlserverA imagem GHCR padrão é Postgres. Para SQL Server, a tag …-sqlserver precisa
existir no registry (a CI publica), ou builde do fonte:
./scripts/deploy-stack.sh <grupo> --build. Detalhes em
Bancos Suportados.
§Verificar
docker ps # banco + app no ar
curl http://localhost:${HSBR_BACK_HOST_PORT}/api/health
curl http://localhost:${HSBR_BACK_HOST_PORT}/license/status # active: true
# Banco direto (opcional):
# Postgres: psql -h 127.0.0.1 -p $POSTGRES_HOST_PORT -U postgres -d $HSBR_DB_NAME -c '\dt' | head
# SQL Server: sqlcmd -S 127.0.0.1,$DB_MSSQL_PORT -U sa -P "$DB_MSSQL_SA_PASSWORD" -C -Q "SELECT name FROM sys.databases"
Parar / apagar o banco
# Postgres
docker compose --project-name h1-db-postgres -f docker-compose.db-postgres.yml down # para (mantém dados)
docker compose --project-name h1-db-postgres -f docker-compose.db-postgres.yml down -v # ⚠ apaga o volume
# SQL Server
docker compose --project-name h1-db-sqlserver -f docker-compose.db-sqlserver.yml down
docker compose --project-name h1-db-sqlserver -f docker-compose.db-sqlserver.yml down -v # ⚠ apaga o volume
Troubleshooting
Sintomas reais de um deploy SQL Server (valem para Postgres-container também):
| Sintoma | Causa | Fix |
|---|---|---|
Banco (healthy) mas back loopa P1001 (migrate) + ETIMEOUT (seed) | Dentro do container, host.docker.internal = gateway da bridge (172.17.0.1), não o loopback do host. Banco publicado em 127.0.0.1 é invisível; ou o UFW dropa o tráfego container→host (é INPUT, e o UFW filtra — diferente dos ports publicados pelo Docker). | Os db-*.sh atuais já publicam no gateway e testam. UFW: ufw allow from 172.16.0.0/12 to any port <porta-db> proto tcp |
P1000 Authentication failed (sa) | Você está acertando outro SQL Server (ex.: um mssql-server nativo na 1433 — systemctl status mssql-server), ou o volume do container guardou uma senha antiga de uma tentativa anterior. | Porta dedicada (DB_MSSQL_PORT=14333); ou recriar do zero: docker rm -f h1-db-sqlserver && docker volume rm h1-db-sqlserver_h1-mssqldata → db-sqlserver.sh |
db-sqlserver.sh falha: porta em uso | Algo já escuta na DB_MSSQL_PORT (cheque ss -ltnp | grep <porta>). | Troque a porta no .env (uma variável só, tudo acompanha) |
Back "healthy" mas /user/signin 500 | O healthcheck não testa o banco; migrate failed — continuing no boot deixou o schema vazio. | docker logs <back> | head -30 mostra o erro real; resolva o item acima e docker restart (migrate roda em todo boot) |
| Login 401 com banco OK | Seed nunca rodou (HSBR_RUN_SEED=0 no 1º boot). | HSBR_RUN_SEED=1 → re-deploy → volte a 0. Ver Migrations e Seed |
Para testar o alcance exatamente como o app (é o probe dos scripts):
docker run --rm --add-host=host.docker.internal:host-gateway \
busybox:stable sh -c "nc -z -w 5 host.docker.internal <porta-db>" && echo OPEN
Notas para SQL Server em produção
- RAM: SQL Server 2019 quer ~2GB+ — pesado num VPS compartilhado.
- Licença do SQL Server: o container usa
MSSQL_PID=Developer(não licenciado para produção). Para produção, use uma edição licenciada ou um instance gerenciado (Caminho A). - Backups: o
backup-db.shépg_dump(só Postgres). Para SQL Server useBACKUP DATABASE/sqlcmdou o backup do instance gerenciado.