Self-Hosting de Múltiplas Instâncias de Banco de Dados em um Único Servidor
A promessa do self-hosting de bancos de dados
Bancos de dados gerenciados na nuvem são convenientes — até a fatura chegar. Para equipes que gerenciam múltiplos projetos, cada um exigindo sua própria instância Postgres, a aritmética de custos muda drasticamente quando você ultrapassa três ou quatro bancos de dados.
Mas, na prática, colocar múltiplas instâncias de banco de dados em uma única máquina não é simplesmente uma questão de executar mais contêineres. Contenção de memória, conflitos de I/O em disco e orquestração de backups tornam-se preocupações relevantes que os serviços gerenciados resolvem silenciosamente por você.
Nossa configuração: múltiplas stacks Supabase em um servidor
Executamos várias stacks completas do Supabase — cada uma composta por Postgres, GoTrue, PostgREST, Realtime e Storage — em um único servidor dedicado. O servidor é uma máquina com 16 vCPUs e 32 GB em um data center europeu, orquestrado inteiramente pelo Docker Compose.
Cada stack tem seu próprio compose file, seu próprio namespace de rede e seu próprio volume de dados. A decisão arquitetural chave: nenhum cluster Postgres compartilhado. Cada projeto recebe uma instância de banco de dados completamente isolada. O custo de executar múltiplos processos Postgres é real — aproximadamente 200-400 MB por instância ociosa — mas a simplicidade operacional do isolamento completo supera o custo de recursos.
Limites de recursos que realmente importam
services:
db:
image: supabase/postgres:15.6
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 512M
cpus: '0.5'Os limites de recursos do Docker são a primeira linha de defesa. Sem eles, uma única query descontrolada pode privar todos os outros bancos de dados da máquina. A reserva garante que cada instância sempre tenha uma alocação mínima, mesmo sob contenção.
Orquestração de backups entre instâncias
O problema com múltiplos bancos de dados não é fazer o backup em si — o pg_dump lida com isso de forma confiável. O problema é orquestrar os backups para que não rodem todos simultaneamente e saturem o I/O do disco.
Escalonamos os backups usando um cronograma simples com offsets no cron. A Instância A faz backup às 02:00, a Instância B às 02:15, a Instância C às 02:30. Cada backup é comprimido com gzip e enviado para armazenamento de objetos. Janela total de backup para todas as instâncias: menos de 45 minutos.
Monitoramento sem uma stack de monitoramento
Uma armadilha comum: implantar Prometheus, Grafana e AlertManager para monitorar um servidor — consumindo assim os recursos que você está tentando proteger. Para nossa escala, uma abordagem leve funciona melhor.
Um script shell roda a cada cinco minutos via cron, verifica cada instância Postgres com pg_isready, mede o uso de disco por volume e envia um resumo para um endpoint de notificação se algum limite for ultrapassado. Custo total de recursos: negligenciável.
Quando parar de fazer self-hosting
Fazer self-hosting de múltiplos bancos de dados faz sentido quando a equipe entende as operações do Postgres, as cargas de trabalho são previsíveis e a economia de custos justifica o overhead operacional. No momento em que qualquer uma dessas condições muda — requisitos de escalabilidade rápida, mandatos de conformidade para serviços gerenciados ou rotatividade da equipe — o cálculo muda de volta para ofertas gerenciadas.
As melhores decisões de infraestrutura são reversíveis. Volumes Docker podem ser exportados, arquivos pg_dump podem ser restaurados em qualquer lugar e a camada de aplicação não deveria se importar com onde seu banco de dados vive. Essa portabilidade é o valor real da abordagem containerizada — não a economia de custos.