Tutoriais de VPS
Supabase auto-hospedado em VPS (2026): Docker Compose, HTTPS, backups e guia de custos de configuração
Qual o tamanho de VPS necessário para o Supabase auto-hospedado? Este artigo compara os custos e os limites operacionais da versão em nuvem com a auto-hospedagem, configura chaves, Caddy HTTPS, SMTP, Storage, backups e atualizações seguindo o processo oficial do Docker, e soluciona problemas de OOM, pool de conexões e falhas de e-mail.

Se você está apenas fazendo um MVP pequeno e ninguém da equipe quer ficar de olho em backups e atualizações a longo prazo, não se apresse em auto-hospedar: use o Supabase Cloud e economize dor de cabeça. A auto-hospedagem em VPS só vale a pena começar quando você claramente precisa de controle de dados, carga estável, políticas de rede especiais, ou precisa manter os componentes e o ritmo de backup nas próprias mãos.
É também aqui que muita gente erra a conta: o Supabase auto-hospedado não é "comprar uma máquina de 2 núcleos e 4 GB e economizar", mas sim assumir a responsabilidade pelo banco de dados, gateway, autenticação, armazenamento de objetos, e-mail, backups e atualizações, tudo de uma vez. O texto a seguir segue a rota oficial do Docker em 2026 e tenta deixar as armadilhas claras de uma vez.
| Opção | Do que o custo mensal é composto principalmente | Responsabilidade operacional | Backup e recuperação | Ritmo de atualização | Localização dos dados e rede | Para quem é mais adequado |
|---|---|---|---|---|---|---|
| Supabase Cloud | Plano da plataforma, uso excedente, recursos adicionais | A plataforma cuida da disponibilidade do serviço subjacente; você gerencia principalmente o negócio | Mais recursos da plataforma; você foca em exportações e simulações na camada de negócio | Segue o ritmo da plataforma | Opções de região limitadas, mas sem se preocupar com detalhes de entrada pública e proxy reverso | Equipes pequenas, MVPs, projetos sem plantão |
| Auto-hospedagem em VPS | VPS, backups externos, SMTP, armazenamento de objetos opcional, tempo de manutenção | Você mesmo cuida de Docker, HTTPS, monitoramento, chaves e recuperação | Banco de dados, Storage, Functions e chaves ficam todos por sua conta | Você decide quando atualizar e também assume o rollback | Você pode escolher o data center, DNS, entrada e firewall, mas também precisa cobrir o respaldo | Equipes com capacidade de operação, carga relativamente estável e necessidade de controlar a localização dos dados |
Detalhando um pouco mais:
- Custo mensal: na nuvem é principalmente plano e uso excedente; na auto-hospedagem é preciso contar pelo menos o VPS, os backups externos, o SMTP, o armazenamento de objetos opcional e o tempo de manutenção.
- Backups: na nuvem a plataforma faz muita coisa por você; na auto-hospedagem você precisa provar que o banco de dados, os arquivos e as chaves podem ser recuperados.
- Atualizações: o que na nuvem se resolve com alguns cliques, na auto-hospedagem exige ler o
CHANGELOG.md, verificar combinações de versões e preparar o rollback. - Localização dos dados: a nuvem segue as regiões disponíveis; a auto-hospedagem permite escolher o data center e a política de rede, mas as falhas também são suas.
Então sugiro avaliar assim: se você ainda está em dúvida entre "aprender Docker, instalar o Caddy também, o SMTP é complicado?", provavelmente é melhor começar com a versão em nuvem. A auto-hospedagem só vale a pena quando duas premissas se cumprem ao mesmo tempo: primeiro, você realmente precisa de controle de dados, limites de rede ou integração de componentes mais flexível; segundo, você aceita que antes de cada atualização futura terá que fazer backup, verificar versões e preparar o rollback.
Se for mesmo comprar uma máquina, passe primeiro pelo raciocínio básico de configuração; você pode aproveitar e ver este guia de escolha de configuração de VPS.
De acordo com a stack oficial de auto-hospedagem atual, 2 vCPU, 4 GB de RAM, 40 GB de SSD é o ponto de partida em que o conjunto completo de componentes consegue rodar, e a linha de base atual do banco de dados é o Postgres 17. Se você pretende rodar um projeto de produção a longo prazo, recomendo começar por 4 vCPU, 8 GB de RAM, 80 GB de SSD.
Ambos os níveis são apenas pontos de partida, não promessas de capacidade, e muito menos garantias de QPS. O motivo é simples: o Supabase não é uma aplicação de contêiner único; ele sobe pelo menos Postgres, Studio, Kong, Auth, PostgREST, Realtime, Storage, imgproxy, Edge Runtime e Supavisor.
Ou seja, 2 núcleos e 4 GB é mais a linha em que "a stack completa consegue ser implantada, verificada e rodar com pouco tráfego"; 4 núcleos e 8 GB é a linha em que você não vai se atrapalhar ao fazer atualizações, rodar backups e ativar monitoramento. Se você também roda outros serviços Docker na mesma máquina, deixe folga de memória.
Também não olhe só para o tamanho da imagem do sistema no disco. O diretório de dados do banco, o WAL, os arquivos do Storage, as Functions e os pacotes compactados de backup crescem continuamente, e 40 GB podem ser consumidos rapidamente. Comece direto com 80 GB em ambientes de produção; depois será muito mais confortável ao fazer backups e simulações de recuperação.
Muita gente, ao ver o Supabase pela primeira vez, acha erroneamente que é só "Postgres + um painel de administração". Na verdade não é.
- Postgres 17 é a camada de dados central;
- Kong cuida do gateway de API;
- Auth cuida do cadastro, login e callbacks de OAuth;
- PostgREST expõe a API REST;
- Realtime cuida de assinaturas e WebSocket;
- Storage lida com arquivos;
- imgproxy lida com transformações de imagem;
- Studio é a interface de administração;
- Edge Runtime executa as Functions;
- Supavisor cuida do pool de conexões.
Por isso esse tipo de projeto não pode olhar só para "se os contêineres sobem", mas também para verificações de saúde, espaço em disco, modos de pool de conexões, SMTP e a cadeia de backup. Esses custos periféricos são os mais fáceis de passar despercebidos em ambientes de produção com Docker; para ideias relacionadas, você pode comparar com este guia de verificações de saúde e limites de recursos em produção com Docker Compose.
Antes de começar de verdade, prepare o seguinte:
- Um VPS Linux limpo;
- Git, Docker Engine, Docker Compose v2;
- Um domínio real já apontando para o VPS;
- A entrada pública abre apenas 80/443; o SSH 22 só permite acesso de IPs confiáveis, bastion host, VPN ou lista de permissões do firewall na nuvem;
- Um diretório de implantação separado e espaço em disco que possa crescer de forma sustentável.
"Abrir apenas 80/443" aqui não é slogan, mas para evitar que depois a porta de desenvolvimento do Kong, a porta do banco de dados e a porta do pool de conexões sejam expostas todas juntas. Muita gente, na primeira auto-hospedagem, assim que os contêineres sobem, coloca sem pensar 5432, 6543, 8000 e 8443 na internet pública; a curto prazo economiza trabalho, a longo prazo é fonte de incidentes.
Para o processo principal, recomenda-se seguir diretamente o diretório oficial do Docker e usar um clone esparso para pegar apenas a parte de docker/, sem baixar o repositório inteiro, e sem tratar scripts de um clique de origem desconhecida como caminho principal.
git clone --filter=blob:none --no-checkout --depth=1 --quiet https://github.com/supabase/supabase
cd supabase
git sparse-checkout init --cone
git sparse-checkout set docker
git checkout --quiet
cd ..
mkdir supabase-project
cp -rf supabase/docker/* supabase-project
cp supabase/docker/.env.example supabase-project/.env
cd supabase-project
Em seguida, não se apresse em up -d. Os valores padrão em .env.example são apenas exemplos de desenvolvimento, especialmente e-mail, URLs e chaves; copiá-los diretamente em produção fará com que cadastro, recuperação de senha e OAuth falhem juntos.
Além disso, é melhor manter o diretório de implantação separado, sem misturar com aplicações diversas. Quando depois você fizer backups, migrações, limpeza de pacotes antigos e endurecimento de permissões, quanto mais claros os limites do diretório, menos complicação.
Os scripts auxiliares oficiais já estão disponíveis; execute-os diretamente no diretório Docker copiado:
sh utils/generate-keys.sh
sh utils/add-new-auth-keys.sh --update-env
O segundo script atualizará o .env depois de gerar novas chaves de auth, então o mais prático é rodar os scripts primeiro e depois voltar para verificar as variáveis. Em seguida, revise o .env pelo menos por grupos:
- Senha do banco de dados;
- Chaves JWT / API;
- Credenciais de login do Studio;
- Diversas chaves de criptografia;
SUPABASE_PUBLIC_URL;API_EXTERNAL_URL;SITE_URL;- lista de permissões de redirecionamento;
- SMTP;
- credenciais opcionais de armazenamento compatível com S3.
A melhor prática nesta etapa não é "preencher qualquer coisa primeiro e corrigir quando der erro", mas organizar de uma vez os endereços externos, o envio de e-mail, as chaves e as contas do painel de administração. Porque muitos problemas no Supabase não são falhas pontuais, mas falhas em cadeia: por exemplo, se você só altera o SITE_URL e não o API_EXTERNAL_URL, na superfície o console abre, mas os links de e-mail e os callbacks de OAuth continuam errados.
Aqui há duas coisas especialmente fáceis de errar:
- O
API_EXTERNAL_URLdeve ser um endereço externo válido com protocolo, e o caminho deve terminar em/auth/v1. - O
SITE_URLaponta para a origem da sua aplicação, não para um endereço de console qualquer.
Além disso, o SERVICE_ROLE_KEY só pode ficar no lado do servidor; não o coloque em variáveis de build do frontend, páginas estáticas ou repositórios públicos.
De acordo com a linha de base oficial atual, a 5432 do Supavisor é modo session e a 6543 é modo transaction. Nenhuma das duas portas deve ser exposta diretamente para toda a internet pública, e muito menos escrita como 0.0.0.0/0 no grupo de segurança.
Se você só acessa de dentro dos contêineres, use a rede interna padrão; se realmente precisar de acesso remoto ao banco de dados, pelo menos adicione regras de origem confiável, VPN, túnel SSH ou rede privada.
Reforço mais uma vez: não trate "conseguir conectar ao banco de dados pela internet externa" como critério de implantação bem-sucedida. Para a maioria dos negócios, a única coisa que realmente deveria ser exposta à internet pública é a entrada do site; o banco de dados e o pool de conexões devem ficar dentro do limite da rede interna o máximo possível.
Mantenha a ordem oficial para os comandos de inicialização e verificação de saúde:
docker compose pull
docker compose up -d --wait
docker compose ps
Se nesta etapa houver contêineres reiniciando repetidamente, não pense primeiro em redefinir os dados; verifique primeiro os logs e o disco. O reset.sh não é um botão de solução de problemas do dia a dia; usar errado significa apagar dados.
Para ambientes de produção, recomenda-se adicionar diretamente o overlay oficial do Caddy:
sh run.sh config add caddy
sh run.sh start
Nesta etapa você precisa confirmar três coisas:
- O DNS já aponta para o VPS atual;
- Na internet pública só é necessário
80/443; - O WebSocket do Realtime também passa pelo proxy reverso via HTTPS.
O 8000/8443 comum em desenvolvimento e o 5432/6543 relacionado ao banco de dados não deveriam ser abertos diretamente para toda a rede. A porta de desenvolvimento do Kong deve ser recolhida, e a entrada externa entregue de forma unificada ao Caddy. Para organizar o proxy reverso e o processo de certificados automáticos, você pode comparar com este guia de HTTPS automático com proxy reverso Caddy.
Se você também precisa que as assinaturas do Realtime, o painel de administração e a API estejam disponíveis ao mesmo tempo, também não abra um segundo conjunto de portas públicas; é mais claro deixar o Caddy cuidar do TLS e da entrada de forma unificada. Assim, quando surgirem problemas de certificado, redirecionamento ou WebSocket, você só precisa olhar para uma camada de entrada.
Primeiro o e-mail. Muita gente descobre após uma instalação bem-sucedida que os e-mails de cadastro não são enviados e que os links de redefinição de senha não funcionam; no fundo não é que o Supabase esteja "quebrado", mas que ainda estão usando a configuração SMTP falsa do .env.example. Em produção é preciso trocar por um serviço SMTP real e verificar o domínio do remetente, a porta, o método de autenticação e o endereço de resposta.
Depois as URLs. SUPABASE_PUBLIC_URL, API_EXTERNAL_URL, SITE_URL e o callback de OAuth devem ser endereços válidos dentro da mesma lógica externa; caso contrário, o problema mais comum é: o console abre, mas os links de e-mail vão para o domínio errado, ou o callback de login de terceiros retorna 400.
Mais uma observação baseada em experiência: se no futuro você for implantar a aplicação e o Supabase em domínios separados, ainda mais motivo para organizar esses endereços cedo. Ser preguiçoso no desenvolvimento e preencher à força um endereço temporário costuma obrigar a refazer modelos de e-mail, listas de permissões de redirecionamento e login de terceiros juntos ao mudar para o domínio de produção no lançamento.
O Storage por padrão coloca os arquivos no ./volumes/storage/ local. Se for apenas um projeto de máquina única, isso é o mais prático; só mude para um backend compatível com S3, como S3 ou R2, quando você claramente precisar desacoplar os arquivos do ciclo de vida do host, quiser compartilhamento entre máquinas ou sua estratégia de backup já exigir armazenamento de objetos. Não há necessidade de colocar outro MinIO no mesmo VPS por "completude arquitetural". Para saber quando usar armazenamento de objetos, você pode seguir este quando um VPS precisa de armazenamento de objetos.
O que mais se esquece no Supabase auto-hospedado não é o SQL, mas os outros arquivos necessários para restaurar uma instância completa. No mínimo, guarde separadamente estas categorias:
- Backup lógico do banco de dados;
pgsodium_root.key;volumes/storage;volumes/functions;.env,docker-compose.yml,docker-compose*.yml,volumes/api,volumes/proxy,volumes/poolere outras configurações vigentes.
Você pode começar com este conjunto de comandos:
mkdir -p backups
docker exec supabase-db pg_dumpall -h localhost -U supabase_admin > "backups/supabase-$(date +%F).sql"
docker compose run --rm db cat /etc/postgresql-custom/pgsodium_root.key > "backups/pgsodium_root.key"
tar -czf "backups/supabase-files-$(date +%F).tar.gz" volumes/storage volumes/functions
tar -czf "backups/supabase-config-$(date +%F).tar.gz" .env docker-compose.yml docker-compose*.yml volumes/api volumes/proxy volumes/pooler
Todos esses arquivos devem ser criptografados ou ter permissões estritamente controladas, e copiados para outro domínio de falha; não podem ficar apenas no mesmo VPS. .env e pgsodium_root.key menos ainda devem ser enviados ao Git. Para saber como fazer simulações de recuperação em uma estratégia de backup, você pode consultar este guia de backup, recuperação e simulações em VPS.
Muitas equipes dizem que "têm backups", mas na realidade só exportam um arquivo SQL para o disco local todos os dias. Quando surge um problema real, você ainda tem que lidar com arquivos do Storage sumidos, Functions perdidas, a chave raiz de criptografia desaparecida e a configuração SMTP esquecida. Poder restaurar uma instância completa não depende de o pg_dumpall ter rodado, mas de você ter guardado todas essas peças do quebra-cabeça juntas.
Em atualizações de produção, a ordem correta deve ser: primeiro ler o CHANGELOG.md e o versions.md no diretório oficial do Docker para confirmar o que essa mudança afeta; depois fazer um backup completo; em seguida atualizar a configuração oficial do Compose e baixar o mesmo conjunto de versões já testadas; por fim reiniciar e verificar o estado de saúde. Um lembrete: alguns documentos de Restore ainda mencionam PG15, mas o guia atual de implantação com Docker, os CHANGELOG.md/versions.md do Docker e o guia de atualização para PG17 já tratam o PG17 como linha de base vigente; para julgar versões, use estes últimos como referência.
Nunca, por pressa, mude a imagem diretamente para latest. O diretório Docker do Supabase é testado por versões agrupadas; perseguir por conta própria uma única imagem latest pode facilmente bagunçar a compatibilidade do Auth, do gateway ou do banco de dados.
As verificações básicas após uma atualização devem incluir pelo menos estas:
docker compose ps
docker stats --no-stream
docker compose logs --since=30m kong auth db supavisor
df -h .
df -i .
Se for OOM, primeiro veja se 2 núcleos e 4 GB já estão saturados pelo Studio, pelas tarefas de backup, pelo banco de dados e pelo tráfego de negócio juntos; se for falha de upload no Storage, verifique primeiro as permissões do disco, o espaço restante e o volumes/storage local; se for anomalia no callback de OAuth, volte imediatamente a verificar a URL externa e a lista de permissões de callbacks.
A ideia central aqui é: primeiro verifique o estado, depois decida se faz rollback. Não apague contêineres nem rode novamente scripts de inicialização assim que ver uma anomalia após a atualização. Enquanto o volume do banco de dados e a configuração não estiverem protegidos primeiro, a solução de problemas facilmente se transforma em um segundo incidente.
Depois de colocar o Supabase auto-hospedado no ar, no mínimo é preciso acompanhar quatro tipos de sinais:
- Se os contêineres se mantêm saudáveis;
- Se a memória está se aproximando do limite;
- Se o espaço em disco e os inodes estão apertados;
- Se
kong,auth,db,supavisorcontinuam dando erro.
Se você ainda não tem uma stack de monitoramento completa, pode começar com a inspeção básica usando o conjunto de comandos acima. Quando o negócio se estabilizar, adicione coleta e alertas mais sistemáticos; caso contrário, quando ocorrer o primeiro OOM ou uma anomalia de certificado, você só poderá adivinhar. Para as ideias de expansão de monitoramento correspondentes, mais adiante você também pode integrar um sistema de coleta mais completo, mas a premissa é colocar primeiro em funcionamento os sinais mais críticos de contêineres e disco.
Roda a stack completa, mas é mais adequado para verificação, pouco tráfego ou projetos internos. Enquanto você também precisar fazer backups, ver logs e rodar outros contêineres de passagem, 4 núcleos e 8 GB será muito mais estável.
Não reinstale primeiro. Verifique primeiro o docker stats --no-stream e os logs dos últimos 30 minutos para confirmar se a memória está saturada pelo Studio, pelas tarefas de backup, pelo banco de dados e pelos picos de negócio juntos. A solução mais comum em uma máquina de 2 núcleos e 4 GB não é "ajustar um monte de parâmetros misteriosos", mas reduzir a concorrência, parar contêineres irrelevantes e, se necessário, subir diretamente para 4 núcleos e 8 GB.
De acordo com a linha de base oficial atual, a 5432 do Supavisor é session e a 6543 é transaction. A maioria das aplicações deve escolher primeiro conforme os cenários recomendados oficialmente, e não expor as duas à internet pública.
Verifique primeiro o SMTP, não culpe o Auth primeiro. Endereços de remetente falsos, portas bloqueadas e TLS mal configurado farão o cadastro e a recuperação de senha falharem juntos.
Primeiro compare SUPABASE_PUBLIC_URL, API_EXTERNAL_URL, SITE_URL, a lista de permissões de redirecionamento e o endereço de callback na plataforma de terceiros. A raiz da maioria dos problemas 400 ou de página errada está nas URLs externas não estarem unificadas.
Verifique primeiro três coisas: se as permissões do ./volumes/storage/ local estão corretas, se há disco e inodes suficientes, e se a entrada de upload ainda passa pelo proxy reverso HTTPS correto. Se você já mudou para S3 ou R2, verifique também credenciais, permissões do bucket e endpoint.
Quando sua contradição principal ainda for "colocar o produto no ar primeiro" e não "preciso controlar eu mesmo a localização dos dados, a rede e o ritmo de atualização", priorize a versão em nuvem.
Em uma frase: sem equipe de operação e com o projeto ainda em fase de tentativa e erro, use o Supabase Cloud; se o negócio já está estável e você está disposto a assumir a longo prazo as responsabilidades de backup, atualização, SMTP e segurança, então vá para a auto-hospedagem em VPS.
O que realmente vale na auto-hospedagem não é "parece que você economizou uma camada de plataforma", mas sim que você sabe por que está assumindo essas responsabilidades e tem os SOPs correspondentes preparados. Enquanto essa premissa não estiver clara, a versão em nuvem geralmente é mais vantajosa.
Por outro lado, se você já tem requisitos claros de localização de dados e quer trazer a entrada, o SMTP, o armazenamento de objetos e a estratégia de backup de volta para seus próprios processos padrão, então esta rota vale a pena ser implementada. Não persiga uma "arquitetura perfeita" de uma vez; colocar a primeira versão rodando de forma estável com o Docker oficial, os scripts de chaves oficiais, o overlay oficial do Caddy e uma cadeia de backup completa é mais importante que qualquer coisa.