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
Windows (Scoop) :
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
Linux / npm :
npm install -g supabase
Vérification :
supabase --version
# supabase 1.x.x
supabase start
Configuration du projet
mkdir my-project && cd my-project
supabase init
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
Démarrage de la stack locale
supabase start
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...
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
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();
Appliquez la migration :
supabase migration up
Génération des types TypeScript
Après chaque modification du schéma :
supabase gen types typescript --local > src/types/database.ts
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
}
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);
Réinitialisez à tout moment :
supabase db reset
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 :
- Créez un nouveau projet Apidog
- Définissez l’URL de base :
http://localhost:54321 - Ajoutez une variable d’environnement :
anon_key = votre-clé-anon-locale - 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}}
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
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' } }
)
})
Tester localement avec rechargement à chaud
supabase functions serve
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"}'
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 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
Dans vos fonctions :
const resendKey = Deno.env.get('RESEND_API_KEY')
// Jamais : const resendKey = 're_xxx'
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
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érezsupabase secrets seten prod. Ajoutez.env*à.gitignore. -
Oublier
supabase db resetaprè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 serveavant. - 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
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 pushetsupabase 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 :
- Installer :
brew install supabase/tap/supabase - Initialiser avec
supabase init - Créer une première migration
- Configurer Apidog pour tester vos endpoints locaux
- 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)