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
    Dica
    O Supabase self-hosted requer VPS com ao menos 4 GB RAM — são muitos containers (PostgreSQL, PostgREST, GoTrue, Realtime, Storage, Studio). Para produção: recomendado 8 GB RAM.

    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"

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes