Supabase self-hosted na VPS

Supabase self-hosted entrega toda a plataforma, PostgreSQL, autenticação, storage, Realtime e o Studio visual, rodando na sua VPS. Ideal para projetos que precisam da conveniência do Supabase Cloud sem os custos recorrentes ou as limitações de dados em servidor externo.

Instalar Supabase self-hosted

O repositório oficial tem um docker-compose.yml completo:

bash
# Clonar repositório oficial do Supabase:
git clone --depth 1 https://github.com/supabase/supabase /opt/supabase
cd /opt/supabase/docker

# Copiar e editar o .env:
cp .env.example .env
nano .env

# Configurações obrigatórias no .env:
# POSTGRES_PASSWORD=senha_forte_do_postgres
# JWT_SECRET=chave-jwt-longa-pelo-menos-32-chars
# ANON_KEY=chave-anon-gerada-com-jwt (ver abaixo)
# SERVICE_ROLE_KEY=chave-service-role-gerada-com-jwt
# DASHBOARD_USERNAME=admin
# DASHBOARD_PASSWORD=senha_do_dashboard
# SITE_URL=https://app.seudominio.com.br
# API_EXTERNAL_URL=https://supabase.seudominio.com.br

# Gerar ANON_KEY e SERVICE_ROLE_KEY:
# Usar https://supabase.com/docs/guides/self-hosting/docker#generate-api-keys

# Subir a stack:
docker compose up -d

# Ver todos os serviços:
docker compose ps

Configurar Nginx para o Supabase

Proxy reverso para API e Studio:

nginx
# /etc/nginx/conf.d/supabase.conf

# API Supabase (PostgREST + GoTrue + Storage)
server {
    listen 443 ssl http2;
    server_name supabase.seudominio.com.br;

    ssl_certificate     /etc/letsencrypt/live/supabase.seudominio.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/supabase.seudominio.com.br/privkey.pem;

    client_max_body_size 500M;

    location / {
        proxy_pass http://127.0.0.1:8000;   # Kong API gateway
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# Studio (interface visual — restrito por IP)
server {
    listen 443 ssl http2;
    server_name studio.seudominio.com.br;

    ssl_certificate     /etc/letsencrypt/live/studio.seudominio.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/studio.seudominio.com.br/privkey.pem;

    allow 177.10.0.1;
    deny all;

    location / {
        proxy_pass http://127.0.0.1:3000;   # Supabase Studio
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Configurar o cliente Supabase JS para self-hosted

Apontar o SDK para o servidor self-hosted:

typescript
// Instalação:
// npm install @supabase/supabase-js

import { createClient } from '@supabase/supabase-js'

// Apontar para o servidor self-hosted:
const supabase = createClient(
  'https://supabase.seudominio.com.br',  // sua URL
  'SUA_ANON_KEY'                          // do .env
)

// Funciona exatamente como o Supabase Cloud:

// Auth
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'usuario@email.com',
  password: 'senha',
})

// Database
const { data: users } = await supabase
  .from('usuarios')
  .select('*')
  .order('criado_em', { ascending: false })

// Storage
const { data } = await supabase.storage
  .from('avatars')
  .upload('user-123.jpg', file)

// Realtime
supabase
  .channel('pedidos')
  .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'pedidos' },
    (payload) => console.log('Novo pedido:', payload))
  .subscribe()

Backup do Supabase self-hosted

Backup completo incluindo banco e storage:

bash
#!/bin/bash
# /opt/scripts/backup-supabase.sh
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="/var/backups/supabase"
mkdir -p "$BACKUP_DIR"

cd /opt/supabase/docker

# 1. Backup do PostgreSQL (contém dados, auth, storage metadata)
docker compose exec -T db \
  pg_dumpall -U postgres | gzip > "$BACKUP_DIR/supabase_pg_${DATE}.sql.gz"

# 2. Backup do Storage (arquivos enviados pelos usuários)
docker run --rm \
  -v supabase_storage:/storage \
  -v "$BACKUP_DIR":/backup \
  alpine tar czf "/backup/supabase_storage_${DATE}.tar.gz" /storage

# 3. Backup das configurações
cp .env "$BACKUP_DIR/supabase_env_${DATE}"

# 4. Upload para S3
aws s3 cp "$BACKUP_DIR/" s3://meu-bucket/supabase/ --recursive \
  --include "*${DATE}*"

find "$BACKUP_DIR" -mtime +7 -delete
echo "Backup Supabase concluído: $DATE"

Atualizar o Supabase self-hosted

Processo seguro de atualização da stack:

bash
cd /opt/supabase/docker

# 1. Fazer backup completo primeiro
/opt/scripts/backup-supabase.sh

# 2. Verificar o changelog antes de atualizar:
# https://github.com/supabase/supabase/releases

# 3. Atualizar o repositório:
git pull origin master

# 4. Atualizar as imagens Docker:
docker compose pull

# 5. Reiniciar com novas versões:
docker compose up -d

# 6. Verificar logs e status:
docker compose ps
docker compose logs --tail=50

# 7. Rodar migrações pendentes (se houver):
docker compose exec db psql -U postgres -c "\l"

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

Cloud: zero manutenção, escala automática, suporte dedicado, mas custos recorrentes e dados nos servidores da Supabase. Self-hosted: custo fixo da VPS, dados na sua infra, sem limites além do hardware, mas você gerencia atualizações e backups. Para startups em fase inicial: Cloud é mais prático. Para dados sensíveis ou grandes volumes: self-hosted faz mais sentido financeiramente.

Quase todas. Features disponíveis: Auth, Database, Storage, Realtime, Edge Functions, Studio. Não disponível no self-hosted: Branching, IA integrada, backups gerenciados automáticos, Network Restrictions avançadas. Para 95% dos casos de uso: self-hosted oferece o necessário.

Cloud Free: projetos pequenos gratuitos com limites (500 MB DB, 1 GB Storage). Cloud Pro: $25/mês + extras. Self-hosted numa VPS 4 GB RAM: ~$20-30/mês na Runstack. Para projetos médios/grandes que pagariam $50-200/mês no Cloud: self-hosted economiza significativamente a longo prazo.

Exportar schema e dados do Cloud: Dashboard → Database → pg_dump. Exportar Auth users: Dashboard → Authentication → Export users. Importar no self-hosted com pg_restore. Atualizar SUPABASE_URL e SUPABASE_ANON_KEY no cliente. Migrar Storage: usar a CLI do Supabase (supabase storage cp) para copiar arquivos entre projetos.

Não nativamente, a stack oficial é para um projeto por instância. Para múltiplos projetos: crie VPSs separadas ou use schemas PostgreSQL diferentes dentro do mesmo banco (mais complexo). Alternativa: use o Supabase Cloud para projetos secundários e self-hosted apenas para o principal.