Rodar PostgreSQL em container Docker não é complicado. O que complica é o entorno: configurar volume persistente, gerenciar credenciais, garantir backup, expor a conexão de forma segura para os serviços que vão consumir o banco, e fazer tudo isso numa infra que responda rápido pro usuário brasileiro. Cada uma dessas tarefas sozinha leva 20 minutos. Juntas, viram um projeto de tarde inteira.
A Guara Cloud resolve esse entorno com o Catálogo de Serviços. Você clica em PostgreSQL, escolhe o plano de recursos, e a plataforma provisiona o container, cria o volume, gera usuário e senha, injeta a string de conexão como variável de ambiente nos serviços do mesmo projeto e configura health check. Em dois minutos você tem um Postgres 17 rodando em São Paulo.
Resposta rápida
Para hospedar PostgreSQL no Brasil, use o Catálogo de Serviços da Guara Cloud. O serviço sobe um container PostgreSQL 17 com volume persistente gerenciado, credenciais geradas automaticamente e descoberta de serviços via variáveis de ambiente. A string de conexão fica disponível nos outros serviços do projeto sem configuração manual. Backups são opcionais e usam snapshots de armazenamento gerenciado.
Principais pontos
- O PostgreSQL roda em container Docker isolado dentro do seu projeto, não é um serviço compartilhado.
- Credenciais (usuário, senha, database name) são geradas automaticamente e ficam no painel.
- A plataforma injeta
DATABASE_URLeDATABASE_HOSTcomo variáveis de ambiente nos serviços do mesmo projeto. - Volume persistente gerenciado garante que os dados sobrevivem a restarts do container.
- O health check da plataforma monitora readiness do banco. Se o processo morrer, o Kubernetes reinicia o pod automaticamente.
- Cobrança em Real, sem conversão de dólar na fatura do cartão.
Quando se aplica
Esse fluxo funciona para qualquer projeto que precisa de um PostgreSQL relacional: APIs REST com Node.js ou NestJS, aplicações Python com Django ou FastAPI, microsserviços Go ou Java que usam JPA. Se a aplicação faz conexão TCP a um banco PostgreSQL, este guia cobre o lado da infraestrutura.
Também serve quando você precisa de um banco para desenvolvimento e staging com a mesma versão da produção. O catálogo oferece PostgreSQL 17, que é a versão estável mais recente com suporte a JSONB, MERGE e logical replication.
Quando não usar este fluxo
Se o projeto requer extensões que não vêm bundladas na imagem oficial do Postgres Alpine (por exemplo, PostGIS para dados geográficos ou pgvector para embeddings), avalie se a extensão está disponível na imagem padrão do catálogo. Caso não esteja, você pode subir o Postgres como serviço custom via Dockerfile próprio.
Para workloads OLAP com queries analíticas pesadas sobre terabytes de dados, PostgreSQL não é a ferramenta certa. Nesse caso, olhe para ClickHouse ou DuckDB. O catálogo da Guara Cloud não cobre esses bancos ainda.
Antes de começar
- Uma conta na Guara Cloud no plano Pro ou superior (o Catálogo de Serviços não está disponível no plano Hobby)
- Um projeto criado no painel
- A aplicação que vai consumir o banco (pode ser um deploy de Node.js, Python, Go, etc.)
1. Provisione o PostgreSQL pelo Catálogo
No painel da Guara Cloud, abra o projeto e clique em “Novo Serviço”. Selecione a aba “Catálogo de Serviços” e escolha “PostgreSQL”. A plataforma apresenta a versão padrão (17 Alpine) e as opções de recursos (CPU e memória).
Passo a passo no painel
- No dashboard do projeto, clique em "Novo Serviço"
- Selecione a aba "Catálogo de Serviços"
- Escolha PostgreSQL na seção de Bancos de Dados
- Selecione o plano de recursos (a recomendação para começar é 512MB RAM e 0.5 vCPU)
- Clique em Deploy
O provisionamento leva entre 30 segundos e 2 minutos. O container sobe, o volume gerenciado é anexado, o processo de initdb roda e o health check passa. Quando o status mudar para “Running”, o banco está pronto.
2. Acesse as credenciais
Depois que o serviço estiver rodando, clique nele no dashboard. A aba “Detalhes” mostra:
Credenciais geradas automaticamente
| Variável | Valor (exemplo) |
|---|---|
POSTGRES_USER | postgres |
POSTGRES_PASSWORD | gerada-automaticamente |
POSTGRES_DB | postgres |
DATABASE_URL | postgres://postgres:***@postgresql:5432/postgres |
Essas credenciais ficam disponíveis no painel e são injetadas como variáveis de ambiente nos demais serviços do mesmo projeto. Se o seu deploy Node.js ou NestJS está no mesmo projeto, ele já enxerga DATABASE_URL sem nenhuma configuração extra.
3. Conecte sua aplicação
No código da sua API, leia a DATABASE_URL do ambiente. Exemplo com Prisma:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
} Ou com TypeORM (NestJS):
TypeOrmModule.forRoot({
type: 'postgres',
url: process.env.DATABASE_URL,
autoLoadEntities: true,
synchronize: false, // nunca true em produção
}) Para aplicações Python com SQLAlchemy:
import os
from sqlalchemy import create_engine
engine = create_engine(
os.environ["DATABASE_URL"],
pool_size=10,
pool_pre_ping=True,
) O pool_pre_ping=True é importante em container. Se o pod do Postgres foi reiniciado, conexões velhas no pool estão mortas. O pre-ping detecta isso e abre uma conexão nova antes de executar a query.
4. Configure variáveis extras se necessário
Algumas aplicações precisam de configurações adicionais no Postgres. Você pode passar parâmetros pelo painel:
Parâmetros comuns de tuning
| Parâmetro | Valor sugerido |
|---|---|
POSTGRES_MAX_CONNECTIONS | 100 |
POSTGRES_SHARED_BUFFERS | 128MB |
POSTGRES_WORK_MEM | 4MB |
Para a maioria das aplicações web pequenas e médias, os padrões do Postgres funcionam bem. Só ajuste quando o EXPLAIN ANALYZE mostrar que precisa.
5. Valide a conexão
Antes de mandar tráfego real, conecte no banco manualmente para confirmar que tudo está funcionando. Use o psql a partir de um dos serviços do projeto (que já tem acesso à rede interna):
psql "$DATABASE_URL" -c "SELECT version();"
# Resultado esperado:
# PostgreSQL 17.x on aarch64-unknown-linux-musl, compiled by gcc (Alpine) Se o psql não está instalado no container da aplicação, faça o teste pelo painel usando o terminal web (disponível na aba do serviço PostgreSQL).
Backup e persistência
O serviço PostgreSQL usa armazenamento persistente gerenciado, que garante que os dados persistem entre restarts. Se o pod morre e o Kubernetes escala um novo, o volume é reanexado automaticamente.
Para backups, o catálogo oferece snapshots de armazenamento gerenciado. Configure a política de snapshot no painel do serviço: frequência (a cada 6h, 12h ou 24h) e retenção (quantos snapshots manter). Um snapshot captura o volume inteiro, então o restore volta o banco ao estado exato daquele momento.
Se o projeto precisa de backup externo (off-site, para compliance ou disaster recovery), faça dump com pg_dump via cron job e envie para o MinIO do catálogo (que é compatível com S3).
pg_dump "$DATABASE_URL" --format=custom --compress=9 > /tmp/backup.dump
# Envie para MinIO/S3 no próximo passo Conexão externa (fora do projeto)
Por padrão, o PostgreSQL do catálogo só é acessível pelos serviços do mesmo projeto via rede interna Kubernetes. Se precisar conectar de fora (um script na sua máquina local, uma ferramenta de BI, um Metabase no servidor do cliente), abra um port-forward pelo painel ou use a URL externa que a Guara Cloud pode gerar para o serviço.
Na prática, manter o banco acessível apenas internamente é mais seguro. Ferramentas de administração como TablePlus ou DBeaver conectam via SSH tunnel ou port-forward sem expor a porta 5432 na internet.
Problemas comuns
- Problema A aplicação não consegue conectar "connection refused"
- Solução Verifique se os dois serviços (banco e aplicação) estão no mesmo projeto e que o PostgreSQL está com status "Running". Se o status é "CrashLoopBackOff", verifique se o volume não está cheio na aba de recursos.
- Problema Timeout na conexão (demora e depois falha)
- Solução O health check do banco pode não ter passado ainda. Espere o status ficar "Running" antes de tentar conectar. Se já está Running, olhe nos logs se o Postgres não está em recovery de crash (demora mais no primeiro boot depois de um restart forçado).
- Problema FATAL: password authentication failed
- Solução A aplicação está usando credenciais hardcoded em vez de ler DATABASE_URL do ambiente. Confirme que o código lê process.env.DATABASE_URL (ou equivalente) e que a variável está visível no deploy.
- Problema Dados sumiram depois de um redeploy
- Solução O volume gerenciado persiste dados entre restarts. Se os dados sumiram, verifique se o volume não foi deletado manualmente ou se o serviço não foi removido e recriado (o que gera um volume novo).
- Problema Queries lentas que funcionavam rápido localmente
- Solução Rode EXPLAIN ANALYZE nas queries problemáticas. Verifique se os índices que existem localmente foram migrados para o banco na nuvem (migrations não rodam automaticamente). Confirme que shared_buffers e work_mem estão adequados para o tamanho dos dados.
Migração de banco existente
Se você já tem um PostgreSQL rodando em outro lugar (AWS RDS, Railway, servidor próprio) e quer trazer para a Guara Cloud, o caminho é:
- Faça
pg_dumpdo banco de origem. - Provisione o PostgreSQL no catálogo da Guara Cloud.
- Use
pg_restoreapontando para aDATABASE_URLdo novo banco. - Valide contagem de registros e alguns selects de conferência.
- Aponte a aplicação para o novo
DATABASE_URL.
# No servidor de origem
pg_dump -h origem.example.com -U user -d meubanco -Fc -f backup.dump
# No container da aplicação Guara Cloud (ou via port-forward)
pg_restore -d "$DATABASE_URL" --no-owner --no-privileges backup.dump Para databases grandes (acima de 5GB), use pg_dump --format=directory --jobs=4 para paralelizar o dump e pg_restore --jobs=4 para paralelizar o restore. A diferença de tempo é significativa.
Escalando o banco
Quando a aplicação cresce, o plano de recursos inicial pode não dar conta. No painel da Guara Cloud, você pode escalar CPU e memória do PostgreSQL sem downtime (o pod faz rolling restart). Os dados ficam no volume persistente, então a troca de container não afeta o conteúdo.
Alguns sinais de que é hora de escalar: CPU constantemente acima de 80%, queries fazendo sequencial scan em tabelas grandes, conexões atingindo o max_connections. Antes de escalar hardware, vale verificar se falta um índice ou se a query pode ser reescrita.
Qual versão do PostgreSQL o catálogo oferece?
PostgreSQL 17 Alpine. É a versão estável mais recente, com suporte a MERGE, melhor performance em JSONB e logical replication aprimorado.
O PostgreSQL é compartilhado entre projetos?
Não. Cada instância é um container dedicado no seu projeto com volume exclusivo. Seus dados não convivem com os de outros clientes.
Posso usar extensões como uuid-ossp ou pgcrypto?
Sim. A imagem oficial do PostgreSQL Alpine inclui as extensões contrib (uuid-ossp, pgcrypto, pg_trgm, entre outras). Basta fazer CREATE EXTENSION depois de conectar.
Quanto custa hospedar PostgreSQL na Guara Cloud?
O custo depende do plano de recursos escolhido (CPU e memória). A cobrança é em Real brasileiro via Stripe, proporcional ao tempo de uso. Não há taxa de setup ou custo de transferência de dados entre serviços do mesmo projeto.
Preciso configurar SSL para a conexão entre a aplicação e o banco?
Não. A comunicação entre serviços no mesmo projeto trafega na rede interna Kubernetes, que é isolada por namespace. SSL na conexão TCP é redundante nesse cenário.
Como faço backup automático?
Configure snapshots de armazenamento gerenciado no painel do serviço PostgreSQL. Escolha a frequência (6h, 12h ou 24h) e a retenção. Os snapshots ficam disponíveis para restore no próprio painel.
Suba seu PostgreSQL na Guara Cloud
Container dedicado, credenciais automáticas, volume persistente e backup com snapshot. Tudo em São Paulo, cobrança em Real.