DEV Community

Cover image for Como Usar Supabase CLI: Guia Completo para Desenvolvedores (2026)
Lucas
Lucas

Posted on • Originally published at apidog.com

Como Usar Supabase CLI: Guia Completo para Desenvolvedores (2026)

TL;DR

Supabase CLI executa uma pilha Supabase completa na sua máquina usando Docker: PostgreSQL, Auth, Storage e Edge Functions. Instale com brew install supabase/tap/supabase, execute supabase init e supabase start para iniciar o ambiente local, depois use supabase db push e supabase functions deploy para enviar para produção. É a rota mais rápida para construir e testar backends Supabase localmente sem depender da nuvem.

Introdução

73% dos bugs de backend são encontrados em produção porque os devs pulam testes locais. Com Supabase CLI, isso não é mais desculpa. Você roda um ambiente espelhando a produção na sua máquina em menos de 5 minutos.

Experimente o Apidog hoje

Aqui está o problema real: muitos devs testam direto em produção (arriscado) ou gastam horas montando ambientes locais que nunca batem 100% com a nuvem (frustrante). O Supabase CLI resolve ambos: oferece uma stack local via Docker idêntica à produção. O que funcionar local, vai funcionar na produção.

💡 Se você constrói APIs sobre Supabase, precisa de uma ferramenta para projetar, testar e documentar seus endpoints enquanto desenvolve. O Apidog conecta direto nas APIs REST e GraphQL do Supabase, permitindo testar o backend enquanto constrói localmente.

Teste suas APIs Supabase com Apidog - grátis

Ao final deste guia, você será capaz de:

  • Subir um ambiente Supabase local completo em minutos
  • Gerenciar alterações de schema com migrações versionadas
  • Construir e testar Edge Functions localmente antes do deploy
  • Fazer deploy para produção com um comando

Por que desenvolvimento Supabase local falha sem o CLI

Se já tentou criar um app Supabase sem o CLI, conhece a dor. Três cenários típicos:

Teste direto em produção: Você altera schema no painel do Supabase, funciona, envia o frontend. Dias depois, um colega puxa o repo e o app quebra — o banco local dele não tem a nova coluna.

Ambiente incompatível: Você sobe um PostgreSQL local, replica o schema na mão, perde horas debugando por que as políticas de RLS parecem diferentes. Não são — você só esqueceu uma política.

"Funciona na minha máquina": Sua Edge Function roda no editor da dashboard, mas falha em produção porque você testou com valores hardcoded, não variáveis reais.

Esses casos são comuns. O "schema drift" (bancos locais e remotos fora de sincronia) é o problema nº 1 em times Supabase. O CLI resolve:

  • Migrações deixam mudanças em schema versionadas e reproduzíveis
  • Stack Docker local idêntica à produção (mesma versão do Postgres, mesmo RLS)
  • Serviço de funções local testa Edge Functions com variáveis reais de ambiente

Como o Supabase CLI funciona

A pilha local

Rodando supabase start, o CLI inicializa um Docker Compose com estes serviços:

Serviço Porta Finalidade
PostgreSQL 54322 Seu banco de dados
PostgREST 54321 API REST gerada automaticamente
GoTrue 54321/auth Autenticação
Realtime 54321/realtime WebSocket subscriptions
Storage 54321/storage Armazenamento de arquivos
Studio 54323 Painel visual
Inbucket 54324 Teste de e-mail (captura todos localmente)
Edge Runtime 54321/functions Executor de funções (Deno)

É a mesma stack da Supabase Cloud, rodando local.

Instalação

macOS:

brew install supabase/tap/supabase
Enter fullscreen mode Exit fullscreen mode

Windows (Scoop):

scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
Enter fullscreen mode Exit fullscreen mode

Linux / npm:

npm install -g supabase
Enter fullscreen mode Exit fullscreen mode

Verifique a instalação:

supabase --version
# supabase 1.x.x
Enter fullscreen mode Exit fullscreen mode

supabase start

Configuração do projeto

mkdir my-project && cd my-project
supabase init
Enter fullscreen mode Exit fullscreen mode

Isso cria:

supabase/
├── config.toml       # Portas, configs de auth/storage
├── seed.sql          # Dados de desenvolvimento para resets
└── migrations/       # Histórico de schema versionado
Enter fullscreen mode Exit fullscreen mode

Iniciando a stack local

supabase start
Enter fullscreen mode Exit fullscreen mode

Na primeira vez, baixa ~1GB de imagens Docker. Depois, inicializa em ~10 segundos.

API URL: http://localhost:54321
DB URL:  postgresql://postgres:postgres@localhost:54322/postgres
Studio:  http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Enter fullscreen mode Exit fullscreen mode

Copie a anon key para seu .env.local — será usada no frontend.

Gerenciamento de banco de dados com migrações

Migrações são o core do fluxo do CLI. Cada mudança de schema vira um arquivo SQL versionado e rastreado no Git. Chega de "quem mudou o banco?".

Criando sua primeira migração

supabase migration new create_posts_table
# Cria: supabase/migrations/20260324120000_create_posts_table.sql
Enter fullscreen mode Exit fullscreen mode

Edite o arquivo:

-- Criar tabela de posts com RLS desde o início
CREATE TABLE posts (
  id          UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id     UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
  title       TEXT NOT NULL,
  content     TEXT,
  published   BOOLEAN DEFAULT false,
  created_at  TIMESTAMPTZ DEFAULT NOW(),
  updated_at  TIMESTAMPTZ DEFAULT NOW()
);

-- Habilitar Row Level Security
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Qualquer pessoa pode ler posts publicados
CREATE POLICY "Anyone can read published posts"
  ON posts FOR SELECT
  USING (published = true);

-- Usuários gerenciam seus próprios posts
CREATE POLICY "Users manage own posts"
  ON posts FOR ALL
  USING (auth.uid() = user_id);

-- Atualizar automaticamente 'updated_at' a cada mudança
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER posts_updated_at
  BEFORE UPDATE ON posts
  FOR EACH ROW EXECUTE FUNCTION update_updated_at();
Enter fullscreen mode Exit fullscreen mode

Aplique a migração:

supabase migration up
Enter fullscreen mode Exit fullscreen mode

Gerando tipos TypeScript

Após cada alteração no schema, gere os tipos:

supabase gen types typescript --local > src/types/database.ts
Enter fullscreen mode Exit fullscreen mode

No frontend, tipagem total:

import { Database } from '@/types/database'

type Post = Database['public']['Tables']['posts']['Row']
type NewPost = Database['public']['Tables']['posts']['Insert']

const createPost = async (post: NewPost) => {
  const { data, error } = await supabase
    .from('posts')
    .insert(post)
    .select()
    .single()
  return data
}
Enter fullscreen mode Exit fullscreen mode

Semeando dados de desenvolvimento

Edite supabase/seed.sql:

-- Usuários de teste
INSERT INTO auth.users (id, email) VALUES
  ('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
  ('00000000-0000-0000-0000-000000000002', 'bob@example.com');

-- Posts de teste
INSERT INTO posts (user_id, title, content, published) VALUES
  ('00000000-0000-0000-0000-000000000001', 'Começando com Supabase', 'Aqui está o que eu aprendi...', true),
  ('00000000-0000-0000-0000-000000000002', 'Rascunho: padrões de design de API', 'Trabalho em andamento...', false);
Enter fullscreen mode Exit fullscreen mode

Para resetar e re-seedar:

supabase db reset
Enter fullscreen mode Exit fullscreen mode

Remove tudo, aplica migrações e carrega seed. Ideal para começar do zero.

Testando APIs Supabase com Apidog

Com Supabase local rodando, você já tem uma API REST em http://localhost:54321. O Supabase gera endpoints para cada tabela via PostgREST. Testar manualmente com curl fica inviável rápido, especialmente para cenários de RLS.

O Apidog conecta direto à instância local. Você pode:

  • Salvar requisições como coleções reutilizáveis
  • Testar endpoints como diferentes usuários (trocando ambientes)
  • Adicionar asserções ("resposta contém pelo menos 1 post") e rodar como pacote de testes
  • Compartilhar documentação automática da API com a equipe

Configuração do Apidog com Supabase local:

  1. Crie um projeto no Apidog
  2. Defina a URL base: http://localhost:54321
  3. Adicione a variável de ambiente: anon_key = sua-anon-key-local
  4. Configure o header Authorization: Bearer {{anon_key}}

Testando o endpoint de posts:

GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
Enter fullscreen mode Exit fullscreen mode

Salve como requisição, adicione asserção (ex: resposta com pelo menos um post), e rode a cada alteração de política de RLS. Pegue erros antes de chegar na produção.

Comece a testar suas APIs Supabase com Apidog

Edge Functions: construa e teste localmente

Edge Functions rodam com Deno na borda, perto dos usuários. Ideais para webhooks, jobs background, endpoints com lógica server-side.

Crie uma função

supabase functions new send-welcome-email
Enter fullscreen mode Exit fullscreen mode

Cria supabase/functions/send-welcome-email/index.ts:

import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

serve(async (req) => {
  const { user_id } = await req.json()

  // Service role ignora RLS - use com cuidado
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  )

  const { data: profile } = await supabase
    .from('profiles')
    .select('email, full_name')
    .eq('id', user_id)
    .single()

  // Lógica de envio de e-mail
  console.log(`Enviando e-mail de boas-vindas para ${profile?.email}`)

  return new Response(
    JSON.stringify({ success: true }),
    { headers: { 'Content-Type': 'application/json' } }
  )
})
Enter fullscreen mode Exit fullscreen mode

Teste local com hot reload

supabase functions serve
Enter fullscreen mode Exit fullscreen mode

O serviço observa alterações e recarrega automaticamente.

Teste via curl:

curl -X POST http://localhost:54321/functions/v1/send-welcome-email \
  -H "Authorization: Bearer YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "00000000-0000-0000-0000-000000000001"}'
Enter fullscreen mode Exit fullscreen mode

Deploy para produção

# Deploy de uma função
supabase functions deploy send-welcome-email

# Deploy de todas as funções
supabase functions deploy
Enter fullscreen mode Exit fullscreen mode

Técnicas avançadas e abordagens comprovadas

Gerenciamento de segredos

Nunca deixe chaves de API no código. Use segredos:

# Setar segredos de produção
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx

# Listar segredos
supabase secrets list

# Remover segredo
supabase secrets unset STRIPE_KEY
Enter fullscreen mode Exit fullscreen mode

Acesse no código:

const resendKey = Deno.env.get('RESEND_API_KEY')
// Nunca: const resendKey = 're_xxx'
Enter fullscreen mode Exit fullscreen mode

Branching de banco de dados

Para grandes mudanças de schema, crie uma branch isolada:

supabase branches create feature-payments
supabase branches switch feature-payments

# Faça mudanças, teste, depois mescle
supabase branches merge feature-payments
Enter fullscreen mode Exit fullscreen mode

Mantém seu banco de dev principal limpo.

Erros comuns a evitar

  • Editar banco direto no Studio: sempre use migrações. Edições diretas não são rastreadas.
  • Commitar .env: use supabase secrets set para produção. Adicione .env* ao .gitignore.
  • Pular supabase db reset após pull: após puxar alterações do time, rode o reset para aplicar novas migrações.
  • Não gerar tipos após mudancas: gere tipos TypeScript sempre após mexer no schema.
  • Deploy de funções sem testar local: sempre rode supabase functions serve antes de deploy.
  • Usar service role key no frontend: service role ignora RLS, use só em funções server-side.

Dicas de desempenho

# Pule serviços não usados para economizar memória
supabase start --exclude-studio --exclude-inbucket

# Veja uso de recursos
docker stats
Enter fullscreen mode Exit fullscreen mode

Alternativas e comparações

Recurso Supabase CLI Firebase CLI PlanetScale CLI
Banco local PostgreSQL completo Apenas emulador Só na nuvem
Migrações SQL versionado no Git Sem suporte nativo Branching
Edge Functions Runtime Deno Cloud Functions Não incluído
Auth local GoTrue completo Emulador Não incluído
Código aberto Totalmente aberto Proprietário Proprietário
Geração de tipos Embutida Manual Manual

O emulador do Firebase é bom para protótipos, mas não fornece Postgres real. O branching do PlanetScale é ótimo para schema changes, mas sempre na nuvem. Supabase CLI brilha para times querendo experiência local 100% open source e PostgreSQL de verdade.

Casos de uso no mundo real

SaaS multi-tenant: Startup de fintech gerencia 47 migrações em dev/staging/prod. Políticas RLS testadas localmente com funções diferentes de usuário antes do deploy. Resultado: zero incidentes de schema em produção em 6 meses.

Processamento de pedidos e-commerce: Time usa Edge Functions para webhooks Stripe. Testam payloads localmente com supabase functions serve e eventos reais do Stripe. Deploy caiu de 2h para 15min.

Backend mobile: Equipe React Native gera tipos TypeScript após cada migração e publica como pacote npm interno. Frontend e backend sempre sincronizados. Dúvidas de "quais campos esse endpoint retorna?" acabaram.

Conclusão

O que fazer agora:

  • Subir ambiente Supabase local completo em minutos
  • Usar migrações para versionar cada alteração de schema
  • Testar Edge Functions com hot reload
  • Gerar tipos TypeScript automaticamente do seu schema
  • Deploy rápido com supabase db push e supabase functions deploy
  • Testar APIs com Apidog antes de subir para produção

Esse fluxo traz ganhos imediatos. Sua equipe entrega mais rápido, encontra bugs cedo e nunca mais sofre com "schema drift".

Próximos passos:

  1. Instale: brew install supabase/tap/supabase
  2. Execute supabase init no projeto
  3. Crie sua primeira migração
  4. Configure o Apidog para testar endpoints locais
  5. Faça deploy para produção com confiança

Teste suas APIs Supabase com Apidog - grátis

FAQ

Preciso do Docker para usar o Supabase CLI? Sim. O Docker Desktop precisa estar rodando antes do supabase start. O CLI usa Docker Compose para rodar toda a stack local. Se o Docker não estiver ativo, você verá erro "Cannot connect to Docker daemon".

Como sincronizo meu banco local com a produção? Use supabase db pull para gerar migração do schema remoto, depois supabase db push para aplicar migrações locais na produção. Rode supabase db reset local após o pull para garantir ambiente idêntico.

Posso usar Supabase CLI sem conta Supabase Cloud? Sim. Use o CLI totalmente local para desenvolvimento. Só precisa de supabase login e supabase link quando for fazer deploy.

Como lidar com conflitos de migração em equipe? Puxe sempre as últimas mudanças do Git e rode supabase db reset antes de criar novas migrações. Nomeie migrações de forma descritiva e comunique mudanças que quebram compatibilidade.

Qual a diferença entre supabase db push e supabase migration up? supabase migration up aplica migrações pendentes no banco local. supabase db push aplica para o projeto remoto (produção). Sempre teste local antes.

Posso usar o Supabase CLI em projeto existente? Sim. Execute supabase link --project-ref SEU_ID_DO_PROJETO para linkar, depois supabase db pull para gerar migrações do schema remoto.

Como testar políticas de RLS localmente? Use o Supabase Studio em http://localhost:54323 para alternar funções de usuário, ou teste via API com JWTs diferentes. O Apidog facilita: crie ambientes com tokens de usuários diferentes e teste as mesmas requisições.

O Supabase CLI é gratuito? Sim. CLI é open source e grátis. Desenvolvimento local não custa nada. Você só paga pela Supabase Cloud na produção.

Top comments (0)