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

Ashley Innocent

Ashley Innocent

24 março 2026

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-o com brew install supabase/tap/supabase, execute supabase init e supabase start para iniciar um ambiente local, e então use supabase db push e supabase functions deploy para enviar para produção. É a maneira mais rápida de construir e testar backends Supabase sem tocar na nuvem.

Introdução

73% dos bugs de backend são descobertos em produção porque os desenvolvedores pulam os testes locais. Com Supabase CLI, isso não é mais uma desculpa. Você obtém um ambiente completo equivalente à produção rodando em sua máquina em menos de 5 minutos.

Aqui está o problema real: a maioria dos desenvolvedores testa diretamente em produção (arrisgado) ou gasta horas configurando ambientes locais que nunca correspondem exatamente à nuvem (frustrante). O Supabase CLI resolve ambos. Ele oferece uma pilha local baseada em Docker que espelha a produção exatamente, então o que funciona localmente funciona em produção.

💡
Se você está construindo APIs sobre o Supabase, você vai querer uma ferramenta para projetar, testar e documentar esses endpoints conforme avança. O Apidog se conecta diretamente às APIs REST e GraphQL do Supabase, permitindo que você teste seu backend enquanto o constrói localmente.
botão

Teste suas APIs Supabase com Apidog - grátis

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

Por que o desenvolvimento Supabase local falha sem o CLI

Se você tentou construir um aplicativo Supabase sem o CLI, você conhece a dor. Aqui estão três cenários que acontecem constantemente.

A armadilha do "teste em produção". Você faz uma mudança de esquema diretamente no painel do Supabase. Funciona. Você envia seu frontend. Três dias depois, um colega puxa o repositório e seu aplicativo quebra porque o banco de dados dele não tem a nova coluna.

A incompatibilidade de ambiente. Você configura uma instância local do PostgreSQL, recria manualmente seu esquema Supabase e passa duas horas depurando por que as políticas de Row Level Security (RLS) se comportam de forma diferente localmente. Elas não se comportam de forma diferente. Você perdeu uma política.

O problema do "funciona na minha máquina". Sua Edge Function funciona no editor do painel do Supabase, mas falha em produção porque você testou com valores codificados em vez de variáveis de ambiente reais.

Estas não são situações excepcionais. O "schema drift" (bancos de dados locais e remotos ficando dessincronizados) é o problema nº 1 relatado por equipes que usam Supabase. O CLI corrige todos os três problemas:

Como o Supabase CLI funciona

A pilha local

Quando você executa supabase start, o CLI inicializa uma pilha 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 Serviço de autenticação
Realtime 54321/realtime Inscrições WebSocket
Storage 54321/storage Armazenamento de arquivos
Studio 54323 Painel visual
Inbucket 54324 Teste de e-mail (captura todos os e-mails localmente)
Edge Runtime 54321/functions Executor de funções baseado em Deno

Esta é a mesma pilha rodando na Supabase Cloud. Na sua máquina.

Instalação

macOS:

brew install supabase/tap/supabase

Windows (Scoop):

scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase

Linux / npm:

npm install -g supabase

Verifique se funcionou:

supabase --version
# supabase 1.x.x
supabase start

Configuração do projeto

mkdir my-project && cd my-project
supabase init

Isso cria:

supabase/
├── config.toml       # Portas, configurações de autenticação, configuração de armazenamento
├── seed.sql          # Dados de desenvolvimento carregados em cada reset do banco de dados
└── migrations/       # Histórico de versão do esquema

Iniciando a pilha local

supabase start

A primeira execução baixa cerca de 1 GB de imagens Docker. Depois disso, as inicializações levam cerca de 10 segundos.

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

Copie a anon key para o seu arquivo .env.local. Você precisará dela para o seu frontend.

Gerenciamento de banco de dados com migrações

As migrações são o núcleo do fluxo de trabalho do CLI. Cada alteração de esquema se torna um arquivo SQL versionado e rastreado no Git. Chega de "quem mudou o banco de dados e quando".

Criando sua primeira migração

supabase migration new create_posts_table
# Cria: supabase/migrations/20260324120000_create_posts_table.sql

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();

Aplique-o:

supabase migration up

Gerando tipos TypeScript

Após cada alteração de esquema, regenere seus tipos:

supabase gen types typescript --local > src/types/database.ts

Seu frontend obtém total segurança de tipo:

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

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

// Agora seu editor detecta erros de tipo antes do tempo de execução
const createPost = async (post: NewPost) => {
  const { data, error } = await supabase
    .from('posts')
    .insert(post)
    .select()
    .single()
  return data
}

Semeando dados de desenvolvimento

Edite supabase/seed.sql:

-- Usuários de teste (ignora autenticação para desenvolvimento local)
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);

Redefina e semeie novamente a qualquer momento:

supabase db reset

Isso remove tudo, executa novamente todas as migrações e carrega seus dados de seed. Execute-o todas as manhãs para começar do zero.

Testando APIs Supabase com Apidog

Uma vez que seu Supabase local esteja em execução, você terá uma API REST totalmente funcional em http://localhost:54321. O Supabase gera automaticamente endpoints para cada tabela via PostgREST. Testá-los manualmente com curl se torna tedioso rapidamente, especialmente quando você precisa testar políticas de RLS com diferentes tokens de usuário.

O Apidog se conecta diretamente à sua instância local do Supabase. Você pode:

Configurando Apidog com Supabase local:

  1. Crie um novo 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. Adicione o cabeçalho de Autorização: 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}}

Salve isso como uma requisição, adicione uma asserção de que a resposta contém pelo menos um post e execute-a toda vez que você mudar suas políticas de RLS. Você pegará políticas quebradas antes que elas cheguem à produção.

Comece a testar suas APIs Supabase com Apidog

Edge Functions: construa e teste localmente

As Edge Functions são executadas em Deno na borda, perto de seus usuários. Elas são perfeitas para webhooks, jobs em segundo plano e endpoints de API que precisam de lógica no lado do servidor.

Crie uma função

supabase functions new send-welcome-email

Isso 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()

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

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

Teste localmente com recarga instantânea (hot reload)

supabase functions serve

O servidor de funções observa as alterações de arquivo e recarrega automaticamente. Teste-o:

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"}'

Deploy para produção

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

# Fazer deploy de todas as funções
supabase functions deploy

Técnicas avançadas e abordagens comprovadas

Gerenciamento de segredos

Nunca codifique chaves de API diretamente em suas funções. Use segredos:

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

# Listar todos os segredos
supabase secrets list

# Remover um segredo
supabase secrets unset STRIPE_KEY

Acesse-os nas funções:

const resendKey = Deno.env.get('RESEND_API_KEY')
// Nunca: const resendKey = 're_xxx'

Branching de banco de dados

Trabalhando em uma grande mudança de esquema? Crie uma branch isolada:

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

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

Isso mantém seu banco de dados de desenvolvimento principal limpo enquanto você experimenta.

Erros comuns a evitar

Editar o banco de dados diretamente no Studio. Sempre use migrações. Edições diretas não são rastreadas e seus colegas de equipe não as terão.

Commitar arquivos .env. Use supabase secrets set para produção. Adicione .env* ao seu .gitignore.

Pular supabase db reset depois de puxar. Quando você puxa as alterações dos colegas de equipe, as novas migrações deles precisam ser executadas localmente. Redefina para aplicá-las.

Não regenerar tipos após alterações de esquema. Seus tipos TypeScript ficam desatualizados no momento em que você adiciona uma coluna. Torne a geração de tipos parte do seu fluxo de trabalho de migração.

Fazer deploy de funções sem testar localmente. Sempre execute supabase functions serve e teste com requisições reais antes de fazer o deploy.

Usar a chave de service role no código do frontend. A chave de service role ignora o RLS. Ela pertence apenas a Edge Functions e código server-side, nunca ao seu navegador.

Dicas de desempenho

# Pule serviços que você não precisa para economizar memória
supabase start --exclude-studio --exclude-inbucket

# Verifique o que está usando recursos
docker stats

Alternativas e comparações

Recurso Supabase CLI Firebase CLI PlanetScale CLI
Banco de dados local PostgreSQL completo Apenas emulador Apenas na nuvem
Migrações Arquivos SQL no Git Sem suporte nativo Branching
Edge Functions Runtime Deno Cloud Functions Não incluído
Auth localmente 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 local do Firebase é bom para prototipagem rápida, mas não oferece uma instância real do PostgreSQL. O modelo de branching do PlanetScale é excelente para alterações de esquema, mas você está sempre trabalhando contra a nuvem. O Supabase CLI se destaca para equipes que desejam uma experiência de desenvolvimento local totalmente de código aberto e nativa do PostgreSQL.

Casos de uso no mundo real

Aplicação SaaS com dados multi-tenant. Uma startup de fintech gerencia 47 migrações em três ambientes (desenvolvimento, staging, produção). As políticas de RLS são testadas localmente com diferentes funções de usuário antes que qualquer código chegue à produção. Resultado: zero incidentes de produção relacionados a esquema em seis meses.

Processamento de pedidos de e-commerce. Uma equipe de e-commerce usa Edge Functions para processamento de webhooks do Stripe. Eles testam payloads de webhook localmente usando supabase functions serve com eventos de teste reais do Stripe. O tempo de deploy caiu de 2 horas para 15 minutos.

Backend de aplicativo móvel. Uma equipe de React Native gera tipos TypeScript após cada migração e os compartilha como um pacote npm interno. Frontend e backend permanecem sincronizados automaticamente. Acabaram as perguntas do tipo "quais campos este endpoint retorna?" no Slack.

Conclusão

Aqui está o que você pode fazer agora:

O fluxo de trabalho compensa imediatamente. Sua equipe envia mais rápido, captura bugs mais cedo e nunca mais lida com o "schema drift".

Seus próximos passos:

  1. Instalar: brew install supabase/tap/supabase
  2. Executar supabase init no seu projeto
  3. Criar sua primeira migração
  4. Configurar o Apidog para testar seus endpoints locais
  5. Fazer o deploy para produção com confiança

Teste suas APIs Supabase com Apidog - grátis

botão

FAQ

Preciso do Docker para usar o Supabase CLI?Sim. O Docker Desktop deve estar em execução antes de supabase start. O CLI usa Docker Compose para executar a pilha completa localmente. Se o Docker não estiver em execução, você receberá um erro de "Cannot connect to Docker daemon".

Como sincronizo meu banco de dados local com a produção?Use supabase db pull para gerar uma migração do seu esquema remoto, então supabase db push para aplicar migrações locais à produção. Execute supabase db reset localmente após puxar para garantir que seu ambiente corresponda.

Posso usar o Supabase CLI sem uma conta Supabase Cloud?Sim. Você pode usar o CLI inteiramente localmente para desenvolvimento sem uma conta na nuvem. Você só precisará de supabase login e supabase link quando estiver pronto para fazer o deploy para produção.

Como lido com conflitos de migração em uma equipe?Puxe as últimas alterações do Git e execute supabase db reset antes de criar novas migrações. Use nomes descritivos para as migrações e comunique-se com sua equipe ao fazer alterações de esquema que quebram a compatibilidade.

Qual a diferença entre supabase db push e supabase migration up?supabase migration up aplica migrações pendentes ao seu banco de dados local. supabase db push as aplica ao seu projeto remoto (produção). Sempre teste localmente primeiro.

Posso usar o Supabase CLI com um projeto existente?Sim. Execute supabase link --project-ref SEU_ID_DO_PROJETO para vincular a um projeto existente, então supabase db pull para gerar migrações do seu esquema remoto atual.

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

O Supabase CLI é gratuito?Sim. O CLI é gratuito e de código aberto. O desenvolvimento local não custa nada. Você paga pelos recursos do Supabase Cloud apenas quando faz o deploy para produção.

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs