Forem

Cover image for Comment utiliser Supabase CLI : Guide complet du développeur (2026)
Antoine Laurent
Antoine Laurent

Posted on • Originally published at apidog.com

Comment utiliser Supabase CLI : Guide complet du développeur (2026)

En bref

Le CLI Supabase vous permet d’exécuter une stack Supabase complète en local via Docker : PostgreSQL, Auth, Storage et Edge Functions. Installez-le avec brew install supabase/tap/supabase, initialisez avec supabase init puis lancez supabase start. Utilisez supabase db push et supabase functions deploy pour déployer en production. C’est la façon la plus rapide de développer et tester un backend Supabase sans passer par le cloud.

Essayez Apidog dès aujourd'hui

Introduction

73% des bugs backend sont détectés en production car les tests locaux sont négligés. Avec le CLI Supabase, plus d’excuses : vous obtenez un environnement local identique à la production en moins de 5 minutes.

Le problème courant : tester directement en prod (dangereux) ou passer des heures à configurer un local qui ne reflète jamais vraiment le cloud (frustrant). Le CLI Supabase élimine ces contraintes. Il fournit une stack Docker locale miroir de la prod, pour que ce qui marche en local marche en prod.

💡
Si vous développez des API sur Supabase, utilisez un outil pour concevoir, tester et documenter vos endpoints dès le départ. Apidog se connecte directement aux API REST et GraphQL de Supabase, pour vérifier votre backend localement pendant le développement.

Testez vos API Supabase avec Apidog - gratuitement

À la fin de ce guide, vous saurez :

  • Démarrer une stack Supabase locale en quelques minutes
  • Gérer les changements de schéma via des migrations versionnées
  • Développer et tester les Edge Functions localement avant déploiement
  • Déployer en prod en une commande

Pourquoi le développement Supabase local échoue sans le CLI

Si vous avez déjà tenté de monter une app Supabase sans CLI, vous connaissez ces scénarios :

Test en production.
Vous modifiez le schéma via le dashboard. Ça marche. Vous déployez le front. Trois jours plus tard, un collègue clone le repo et sa base n’a pas la nouvelle colonne.

Environnement incohérent.
Vous installez PostgreSQL localement, essayez de répliquer le schéma à la main, puis passez deux heures à comprendre pourquoi le RLS agit différemment. En fait, il manque une policy.

"Ça marche sur ma machine".
Votre Edge Function marche dans l’éditeur du dashboard, mais échoue en prod car vous utilisiez des valeurs en dur au lieu de vraies variables d’environnement.

La dérive de schéma (base locale/distance désynchronisée) est la plainte n°1 des équipes Supabase. Le CLI règle ces soucis :

  • Les migrations rendent chaque modification de schéma traçable et reproductible.
  • La stack Docker locale reproduit exactement la prod, même version de Postgres, même moteur RLS.
  • Le service de fonctions local permet de tester avec de vraies variables d’environnement.

Comment fonctionne le CLI Supabase

La stack locale

Avec supabase start, le CLI lance un Docker Compose avec ces services :

Service Port Objectif
PostgreSQL 54322 Votre base de données
PostgREST 54321 API REST auto-générée
GoTrue 54321/auth Service d'authentification
Realtime 54321/realtime Abonnements WebSocket
Storage 54321/storage Stockage de fichiers
Studio 54323 Tableau de bord visuel
Inbucket 54324 Test d'e-mails (capture tous les e-mails localement)
Edge Runtime 54321/functions Exécuteur de fonctions basé sur Deno

C’est exactement la même stack que le cloud Supabase, mais en local.

Installation

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

Vérification :

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

supabase start

Configuration du projet

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

Cela génère la structure suivante :

supabase/
├── config.toml       # Ports, params d’auth, config storage
├── seed.sql          # Données de dev rechargées à chaque reset
└── migrations/       # Historique des versions du schéma
Enter fullscreen mode Exit fullscreen mode

Démarrage de la stack locale

supabase start
Enter fullscreen mode Exit fullscreen mode

La première fois, Docker télécharge ~1 Go d’images. Ensuite, ça démarre en ~10 secondes.

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

Copiez la anon key dans votre .env.local pour le frontend.

Gestion de la base de données avec les migrations

Les migrations sont la base du workflow CLI. Chaque modification du schéma devient un fichier SQL versionné et suivi dans Git.

Créer votre première migration

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

Modifiez le fichier :

-- Créer la table des articles avec RLS dès le début
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()
);

-- Activer la sécurité au niveau des lignes
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Tout le monde peut lire les articles publiés
CREATE POLICY "Anyone can read published posts"
  ON posts FOR SELECT
  USING (published = true);

-- Les utilisateurs gèrent leurs propres articles
CREATE POLICY "Users manage own posts"
  ON posts FOR ALL
  USING (auth.uid() = user_id);

-- Mise à jour automatique de updated_at à chaque modification
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

Appliquez la migration :

supabase migration up
Enter fullscreen mode Exit fullscreen mode

Génération des types TypeScript

Après chaque modification du schéma :

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

Dans le frontend, profitez de la sécurité de type :

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

Amorçage des données de développement

Éditez supabase/seed.sql :

-- Utilisateurs de test (contourne l’auth pour le dev local)
INSERT INTO auth.users (id, email) VALUES
  ('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
  ('00000000-0000-0000-0000-000000000002', 'bob@example.com');

-- Articles de test
INSERT INTO posts (user_id, title, content, published) VALUES
  ('00000000-0000-0000-0000-000000000001', 'Getting started with Supabase', 'Here is what I learned...', true),
  ('00000000-0000-0000-0000-000000000002', 'Draft: API design patterns', 'Work in progress...', false);
Enter fullscreen mode Exit fullscreen mode

Réinitialisez à tout moment :

supabase db reset
Enter fullscreen mode Exit fullscreen mode

Cela efface tout, rejoue toutes les migrations et recharge le seed. Pratique pour repartir à zéro.

Tester les API Supabase avec Apidog

Votre Supabase local expose une API REST à http://localhost:54321. Les endpoints pour chaque table sont auto-générés par PostgREST. Tester à la main avec curl devient vite pénible, surtout pour valider le RLS avec différents tokens.

Apidog se connecte directement à votre instance locale. Utilisez-le pour :

  • Organiser vos requêtes sous forme de collections réutilisables
  • Tester chaque endpoint en changeant d’environnement/utilisateur
  • Ajouter des assertions (« la réponse contient au moins 1 article ») et exécuter des suites de tests
  • Partager la doc API avec l’équipe

Configuration d’Apidog avec Supabase local :

  1. Créez un nouveau projet Apidog
  2. Définissez l’URL de base : http://localhost:54321
  3. Ajoutez une variable d’environnement : anon_key = votre-clé-anon-locale
  4. Ajoutez l’en-tête Authorization : Bearer {{anon_key}}

Test du endpoint articles :

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

Enregistrez la requête, ajoutez une assertion sur la réponse, et relancez le test après chaque changement de policy RLS.

Commencez à tester vos API Supabase avec Apidog.

Fonctions Edge : construire et tester localement

Les Edge Functions s’exécutent sur Deno près de l’utilisateur. Idéal pour webhooks, tâches background ou endpoints nécessitant de la logique server-side.

Créer une fonction

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

Cela crée 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()

  // Le rôle de service contourne le RLS - à utiliser avec prudence
  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()

  // Votre logique d’envoi d’e-mail ici
  console.log(`Sending welcome email to ${profile?.email}`)

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

Tester localement avec rechargement à chaud

supabase functions serve
Enter fullscreen mode Exit fullscreen mode

Le serveur de fonctions surveille les fichiers et recharge automatiquement. Testez avec :

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

Déployer en production

# Déployer une fonction
supabase functions deploy send-welcome-email

# Déployer toutes les fonctions
supabase functions deploy
Enter fullscreen mode Exit fullscreen mode

Techniques avancées et bonnes pratiques

Gestion des secrets

Ne codez jamais les clés API en dur. Utilisez les secrets :

# Définir des secrets de prod
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx

# Lister tous les secrets
supabase secrets list

# Supprimer un secret
supabase secrets unset STRIPE_KEY
Enter fullscreen mode Exit fullscreen mode

Dans vos fonctions :

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

Branching de base de données

Pour des modifications majeures du schéma :

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

# Modifiez, testez, puis fusionnez
supabase branches merge feature-payments
Enter fullscreen mode Exit fullscreen mode

Gardez la base principale propre pendant vos expérimentations.

Erreurs courantes à éviter

  • Modifier la DB via Studio. Utilisez toujours les migrations.
  • Commiter les fichiers .env. Préférez supabase secrets set en prod. Ajoutez .env* à .gitignore.
  • Oublier supabase db reset après un pull. Appliquez toujours les migrations de l’équipe.
  • Ne pas regénérer les types après une modif de schéma. Faites-en une étape systématique.
  • Déployer des fonctions sans test local. Toujours tester avec supabase functions serve avant.
  • Utiliser la clé de rôle de service côté frontend. À n’utiliser que côté serveur/Edge Function.

Conseils de performance

# Exclure des services inutiles pour économiser de la RAM
supabase start --exclude-studio --exclude-inbucket

# Suivre la conso mémoire
docker stats
Enter fullscreen mode Exit fullscreen mode

Alternatives et comparaisons

Fonctionnalité CLI Supabase CLI Firebase CLI PlanetScale
Base de données locale PostgreSQL complet Émulateur uniquement Cloud uniquement
Migrations Fichiers SQL dans Git Pas de support natif Branching
Fonctions Edge Runtime Deno Cloud Functions Non inclus
Authentification locale GoTrue complet Émulateur Non inclus
Open source Entièrement ouvert Propriétaire Propriétaire
Génération de types Intégrée Manuelle Manuelle

L’émulateur Firebase est pratique pour prototyper, mais pas de vrai PostgreSQL. PlanetScale offre un bon modèle de branching, mais reste cloud-only. Le CLI Supabase est idéal pour un dev local full open-source et natif PostgreSQL.

Cas d’utilisation réels

SaaS multi-tenant.
Une fintech gère 47 migrations sur 3 environnements (dev, staging, prod). Les policies RLS sont testées localement avec différents rôles. Résultat : zéro incident de prod lié au schéma en 6 mois.

E-commerce et webhooks.
Une équipe e-commerce traite les webhooks Stripe via Edge Functions. Ils testent localement avec supabase functions serve et les events de test Stripe. Temps de déploiement passé de 2h à 15 min.

Backend mobile.
Une équipe React Native génère et partage les types TypeScript à chaque migration via un package npm interne. Front et back toujours synchronisés. Fini les questions « quels champs ce point d’accès renvoie ? ».

En résumé

Ce que vous pouvez faire dès maintenant :

  • Lancer une stack Supabase locale en quelques minutes
  • Versionner chaque modif de schéma avec des migrations
  • Tester les Edge Functions localement avec hot reload
  • Générer les types TypeScript automatiquement
  • Déployer avec supabase db push et supabase functions deploy
  • Tester vos API avec Apidog avant la mise en prod

Ce workflow donne des résultats immédiats : déploiements plus rapides, bugs détectés plus tôt, plus jamais de dérive de schéma.

Prochaines étapes :

  1. Installer : brew install supabase/tap/supabase
  2. Initialiser avec supabase init
  3. Créer une première migration
  4. Configurer Apidog pour tester vos endpoints locaux
  5. Déployer en prod sereinement

Testez vos API Supabase avec Apidog - gratuitement

FAQ

Ai-je besoin de Docker pour utiliser le CLI Supabase ?

Oui. Docker Desktop doit être lancé avant supabase start. Sans Docker, erreur « Cannot connect to Docker daemon ».

Comment synchroniser ma base locale avec la prod ?

Utilisez supabase db pull pour générer une migration depuis le schéma distant, puis supabase db push pour appliquer vos migrations en prod. Faites supabase db reset localement après pull.

Puis-je utiliser le CLI Supabase sans compte Cloud ?

Oui. Utilisation locale 100% offline. Les commandes supabase login et supabase link ne sont requises qu’au déploiement.

Comment gérer les conflits de migration en équipe ?

Récupérez les modifs Git, exécutez supabase db reset avant nouvelle migration. Utilisez des noms explicites et communiquez sur les changements majeurs.

Différence entre supabase db push et supabase migration up ?

supabase migration up applique les migrations à la base locale. supabase db push les pousse en prod. Testez toujours localement avant.

Puis-je utiliser le CLI sur un projet existant ?

Oui. Liez votre projet avec supabase link --project-ref VOTRE_ID_DE_PROJET puis supabase db pull pour générer les migrations à partir du schéma distant.

Comment tester le RLS localement ?

Utilisez Supabase Studio (http://localhost:54323) pour changer de rôle, ou testez l’API avec différents JWT. Apidog simplifie : créez des environnements avec différents tokens et rejouez les requêtes.

Le CLI Supabase est-il gratuit ?

Oui, open source et gratuit pour le dev local. Vous ne payez Supabase Cloud qu’une fois en prod.

Top comments (0)