En bref
Le CLI Supabase exécute une pile Supabase complète sur votre machine à l'aide de Docker : PostgreSQL, Auth (authentification), Storage (stockage) et Edge Functions (fonctions Edge). Installez-le avec brew install supabase/tap/supabase, exécutez supabase init et supabase start pour lancer un environnement local, puis utilisez supabase db push et supabase functions deploy pour déployer en production. C'est le moyen le plus rapide de construire et de tester des backends Supabase sans toucher au cloud.
Introduction
73% des bugs backend sont découverts en production car les développeurs ignorent les tests locaux. Avec le CLI Supabase, ce n'est plus une excuse. Vous obtenez un environnement complet équivalent à la production fonctionnant sur votre machine en moins de 5 minutes.
Voici le vrai problème : la plupart des développeurs testent soit directement en production (risqué), soit passent des heures à configurer des environnements locaux qui ne correspondent jamais tout à fait au cloud (frustrant). Le CLI Supabase résout ces deux problèmes. Il vous fournit une pile locale basée sur Docker qui reproduit exactement la production, de sorte que ce qui fonctionne localement fonctionne aussi en production.
Testez vos API Supabase avec Apidog - gratuitement
À la fin de ce guide, vous serez capable de :
- Mettre en place un environnement Supabase local complet en quelques minutes
- Gérer les modifications du schéma de base de données avec des migrations versionnées
- Construire et tester les fonctions Edge localement avant de les déployer
- Déployer en production avec une seule commande
Pourquoi le développement Supabase local échoue sans le CLI
Si vous avez déjà essayé de créer une application Supabase sans le CLI, vous connaissez la difficulté. Voici trois scénarios qui se produisent constamment.
Le piège du "test en production". Vous effectuez une modification de schéma directement dans le tableau de bord Supabase. Ça fonctionne. Vous déployez votre frontend. Trois jours plus tard, un coéquipier récupère le dépôt et son application ne fonctionne plus car sa base de données ne contient pas la nouvelle colonne.
L'inadéquation de l'environnement. Vous configurez une instance PostgreSQL locale, recréez manuellement votre schéma Supabase et passez deux heures à déboguer pourquoi les politiques de sécurité au niveau des lignes (Row Level Security) se comportent différemment localement. Elles ne se comportent pas différemment. Vous avez oublié une politique.
Le problème du "ça marche sur ma machine". Votre fonction Edge fonctionne dans l'éditeur du tableau de bord Supabase mais échoue en production car vous avez testé avec des valeurs codées en dur au lieu de vraies variables d'environnement.
Ce ne sont pas des cas isolés. La dérive de schéma (bases de données locales et distantes désynchronisées) est le problème n°1 signalé par les équipes utilisant Supabase. Le CLI résout ces trois problèmes :
- Les migrations permettent de contrôler la version des modifications de schéma et de les rendre reproductibles.
- La pile Docker locale reproduit exactement la production, même version de PostgreSQL, même moteur RLS.
- Le service de fonctions local teste les fonctions Edge avec de vraies variables d'environnement.
Comment fonctionne le CLI Supabase
La pile locale
Lorsque vous exécutez supabase start, le CLI lance une pile Docker Compose avec les services suivants :
| 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 la même pile qui tourne dans le Supabase Cloud. Sur votre machine.
Installation
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
Vérifiez l'installation :
supabase --version
# supabase 1.x.x
supabase startConfiguration du projet
mkdir my-project && cd my-project
supabase init
Cela crée :
supabase/
├── config.toml # Ports, paramètres d'authentification, configuration du stockage
├── seed.sql # Données de développement chargées à chaque réinitialisation de la base de données
└── migrations/ # Historique des versions du schéma
Démarrage de la pile locale
supabase start
La première exécution télécharge environ 1 Go d'images Docker. Après cela, les démarrages prennent environ 10 secondes.
API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio: http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Copiez la anon key dans votre fichier .env.local. Vous en aurez besoin pour votre frontend.
Gestion de la base de données avec les migrations
Les migrations sont au cœur du flux de travail du CLI. Chaque modification de schéma devient un fichier SQL versionné suivi dans Git. Fini les "qui a modifié la base de données et quand".
Créer votre première migration
supabase migration new create_posts_table
# Creates: supabase/migrations/20260324120000_create_posts_table.sql
Modifiez le fichier :
-- Create posts table with RLS from the start
-- 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()
);
-- Enable Row Level Security
-- Activer la sécurité au niveau des lignes
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Anyone can read published posts
-- Tout le monde peut lire les articles publiés
CREATE POLICY "Anyone can read published posts"
ON posts FOR SELECT
USING (published = true);
-- Users manage their own posts
-- Les utilisateurs gèrent leurs propres articles
CREATE POLICY "Users manage own posts"
ON posts FOR ALL
USING (auth.uid() = user_id);
-- Auto-update updated_at on every change
-- 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();
Appliquez-le :
supabase migration up
Génération des types TypeScript
Après chaque modification de schéma, régénérez vos types :
supabase gen types typescript --local > src/types/database.ts
Votre frontend obtient une sécurité de type complète :
import { Database } from '@/types/database'
type Post = Database['public']['Tables']['posts']['Row']
type NewPost = Database['public']['Tables']['posts']['Insert']
// Maintenant, votre éditeur détecte les erreurs de type avant l'exécution
const createPost = async (post: NewPost) => {
const { data, error } = await supabase
.from('posts')
.insert(post)
.select()
.single()
return data
}
Amorçage des données de développement
Modifiez supabase/seed.sql :
-- Test users (bypasses auth for local dev)
-- Utilisateurs de test (contourne l'authentification pour le développement local)
INSERT INTO auth.users (id, email) VALUES
('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
('00000000-0000-0000-0000-000000000002', 'bob@example.com');
-- Test posts
-- 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);
Réinitialisez et réinitialisez les données à tout moment :
supabase db reset
Cela supprime tout, réexécute toutes les migrations et charge vos données d'amorçage. Exécutez-le chaque matin pour repartir à zéro.
Tester les API Supabase avec Apidog
Une fois que votre Supabase local est en cours d'exécution, vous disposez d'une API REST entièrement fonctionnelle à l'adresse http://localhost:54321. Supabase génère automatiquement des points d'accès pour chaque table via PostgREST. Tester cela manuellement avec curl devient vite fastidieux, surtout lorsque vous devez tester des politiques RLS avec différents jetons utilisateur.
Apidog se connecte directement à votre instance Supabase locale. Vous pouvez :
- Enregistrer des requêtes sous forme de collections réutilisables
- Tester le même point d'accès en tant qu'utilisateurs différents en changeant d'environnement
- Ajouter des assertions (« la réponse contient au moins 1 article ») et les exécuter comme une suite de tests
- Partager automatiquement la documentation de l'API avec votre équipe
Configuration d'Apidog avec Supabase local :
- Créer un nouveau projet dans Apidog
- Définir l'URL de base :
http://localhost:54321 - Ajouter une variable d'environnement :
anon_key = votre-clé-anon-locale - Ajouter l'en-tête d'autorisation :
Bearer {{anon_key}}
Tester le point d'accès des articles :
GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
Enregistrez ceci comme une requête, ajoutez une assertion selon laquelle la réponse contient au moins un article, et exécutez-la chaque fois que vous modifiez vos politiques RLS. Vous détecterez les politiques défectueuses avant qu'elles n'atteignent la production.
Commencez à tester vos API Supabase avec Apidog
Fonctions Edge : construire et tester localement
Les fonctions Edge s'exécutent sur Deno en périphérie, à proximité de vos utilisateurs. Elles sont parfaites pour les webhooks, les tâches en arrière-plan et les points d'accès API nécessitant une logique côté serveur.
Créer une fonction
supabase functions new send-welcome-email
Ceci 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' } }
)
})
Tester localement avec rechargement à chaud
supabase functions serve
Le serveur de fonctions surveille les modifications de fichiers et se recharge automatiquement. Testez-le :
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"}'
Déployer en production
# Déployer une fonction
supabase functions deploy send-welcome-email
# Déployer toutes les fonctions
supabase functions deploy
Techniques avancées et approches éprouvées
Gestion des secrets
Ne jamais coder en dur les clés API dans vos fonctions. Utilisez des secrets :
# Définir les secrets de production
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
Accédez-y dans les fonctions :
const resendKey = Deno.env.get('RESEND_API_KEY')
// Jamais : const resendKey = 're_xxx'
Branching de base de données
Vous travaillez sur une modification de schéma importante ? Créez une branche isolée :
supabase branches create feature-payments
supabase branches switch feature-payments
# Effectuez les modifications, testez, puis fusionnez
supabase branches merge feature-payments
Cela permet de garder votre base de données de développement principale propre pendant que vous expérimentez.
Erreurs courantes à éviter
Modifier la base de données directement dans Studio. Utilisez toujours les migrations. Les modifications directes ne sont pas suivies et vos coéquipiers ne les auront pas.
Commiter les fichiers .env. Utilisez supabase secrets set pour la production. Ajoutez .env* à votre .gitignore.
Omettre supabase db reset après un pull. Lorsque vous récupérez les modifications de vos coéquipiers, leurs nouvelles migrations doivent être exécutées localement. Réinitialisez pour les appliquer.
Ne pas regénérer les types après des modifications de schéma. Vos types TypeScript deviennent obsolètes dès que vous ajoutez une colonne. Faites de la génération de types une partie de votre flux de travail de migration.
Déployer des fonctions sans test local. Exécutez toujours supabase functions serve et testez avec de vraies requêtes avant de déployer.
Utiliser la clé de rôle de service dans le code frontend. La clé de rôle de service contourne le RLS. Elle ne doit être utilisée que dans les fonctions Edge et le code côté serveur, jamais dans votre navigateur.
Conseils de performance
# Ignorer les services dont vous n'avez pas besoin pour économiser de la mémoire
supabase start --exclude-studio --exclude-inbucket
# Vérifier ce qui utilise les ressources
docker stats
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 local de Firebase est bon pour le prototypage rapide mais ne vous donne pas une vraie instance PostgreSQL. Le modèle de branching de PlanetScale est excellent pour les changements de schéma mais vous travaillez toujours contre le cloud. Le CLI Supabase est idéal pour les équipes qui souhaitent une expérience de développement local entièrement open-source et native de PostgreSQL.
Cas d'utilisation réels
Application SaaS avec données multi-locataires. Une startup fintech gère 47 migrations à travers trois environnements (dev, staging, prod). Les politiques RLS sont testées localement avec différents rôles d'utilisateur avant que tout code n'atteigne la production. Résultat : zéro incident de production lié au schéma en six mois.
Traitement des commandes e-commerce. Une équipe e-commerce utilise les fonctions Edge pour le traitement des webhooks Stripe. Ils testent les charges utiles des webhooks localement en utilisant supabase functions serve avec de vrais événements de test Stripe. Le temps de déploiement est passé de 2 heures à 15 minutes.
Backend d'application mobile. Une équipe React Native génère des types TypeScript après chaque migration et les partage en tant que package npm interne. Le frontend et le backend restent synchronisés automatiquement. Fini les questions « quels champs ce point d'accès renvoie-t-il ? » sur Slack.
En résumé
Voici ce que vous pouvez faire maintenant :
- Mettre en place un environnement Supabase local complet en quelques minutes
- Utiliser les migrations pour versionner chaque modification de schéma
- Tester les fonctions Edge localement avec rechargement à chaud
- Générer automatiquement les types TypeScript à partir de votre schéma
- Déployer avec
supabase db pushetsupabase functions deploy - Tester vos API avec Apidog avant de les déployer en production
Ce flux de travail porte ses fruits immédiatement. Votre équipe déploie plus rapidement, détecte les bugs plus tôt et ne gère plus jamais la dérive de schéma.
Vos prochaines étapes :
- Installer :
brew install supabase/tap/supabase - Exécutez
supabase initdans votre projet - Créez votre première migration
- Configurez Apidog pour tester vos points d'accès locaux
- Déployez en production en toute confiance
Testez vos API Supabase avec Apidog - gratuitement
FAQ
Ai-je besoin de Docker pour utiliser le CLI Supabase ?Oui. Docker Desktop doit être en cours d'exécution avant supabase start. Le CLI utilise Docker Compose pour exécuter la pile complète localement. Si Docker n'est pas en cours d'exécution, vous obtiendrez une erreur « Cannot connect to Docker daemon » (Impossible de se connecter au démon Docker).
Comment synchroniser ma base de données locale avec la production ?Utilisez supabase db pull pour générer une migration à partir de votre schéma distant, puis supabase db push pour appliquer les migrations locales à la production. Exécutez supabase db reset localement après un pull pour vous assurer que votre environnement correspond.
Puis-je utiliser le CLI Supabase sans compte Supabase Cloud ?Oui. Vous pouvez utiliser le CLI entièrement localement pour le développement sans compte cloud. Vous n'aurez besoin de supabase login et supabase link que lorsque vous serez prêt à déployer en production.
Comment gérer les conflits de migration en équipe ?Récupérez les dernières modifications Git et exécutez supabase db reset avant de créer de nouvelles migrations. Utilisez des noms de migration descriptifs et communiquez avec votre équipe lorsque vous effectuez des modifications de schéma majeures.
Quelle est la différence entre supabase db push et supabase migration up ?supabase migration up applique les migrations en attente à votre base de données locale. supabase db push les applique à votre projet distant (de production). Testez toujours localement en premier.
Puis-je utiliser le CLI Supabase avec un projet existant ?Oui. Exécutez supabase link --project-ref VOTRE_ID_DE_PROJET pour lier un projet existant, puis supabase db pull pour générer les migrations à partir de votre schéma distant actuel.
Comment tester les politiques RLS localement ?Utilisez Supabase Studio à l'adresse http://localhost:54323 pour basculer entre les rôles d'utilisateur, ou testez via l'API avec différents jetons JWT. Apidog facilite cela : créez plusieurs environnements avec différents jetons utilisateur et exécutez les mêmes requêtes en tant qu'utilisateurs différents.
Le CLI Supabase est-il gratuit ?Oui. Le CLI est gratuit et open source. Le développement local ne coûte rien. Vous ne payez pour les ressources Supabase Cloud que lorsque vous déployez en production.
