📍 Article principal : Supabase 2026 : guide pratique.
Une heure pour installer Supabase complet sur Hetzner CCX13. Méthode validée chez startups francophones d’Afrique de l’Ouest.
Prérequis
- Hetzner CCX13 minimum (8 Go RAM, Postgres + 8 services).
- Docker + Docker Compose plugin.
- Domaine :
api.votre-app.cometstudio.votre-app.com. - Niveau : avancé.
- Temps : 60-90 min.
Étape 1 — Cloner Supabase
git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env
Étape 2 — Variables critiques .env
POSTGRES_PASSWORD=générer-32-octets-fort
JWT_SECRET=générer-32-octets-aleatoire
ANON_KEY=signer-jwt-avec-secret
SERVICE_ROLE_KEY=signer-jwt-avec-secret
SITE_URL=https://votre-app.com
SUPABASE_PUBLIC_URL=https://api.votre-app.com
DASHBOARD_USERNAME=admin
DASHBOARD_PASSWORD=fort
# SMTP pour Auth emails
SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_USER=login
SMTP_PASS=key
SMTP_ADMIN_EMAIL=admin@votre-app.com
SMTP_SENDER_NAME=Votre App
# Storage
GLOBAL_S3_BUCKET=supabase-storage
STORAGE_BACKEND=file
Étape 3 — Générer JWT keys
Outil officiel : supabase.com/docs/guides/self-hosting/docker. Utiliser JWT_SECRET pour signer ANON et SERVICE_ROLE.
Étape 4 — Caddy reverse proxy
api.votre-app.com {
reverse_proxy localhost:8000
}
studio.votre-app.com {
reverse_proxy localhost:3000
}
Étape 5 — Lancer stack
docker compose up -d
docker compose ps # Tous services Up
Étape 6 — Accéder Studio
Ouvrir https://studio.votre-app.com. Login avec DASHBOARD_USERNAME/PASSWORD. Dashboard charge.
Étape 7 — Test API
curl https://api.votre-app.com/rest/v1/ -H "apikey: $ANON_KEY"
# Doit retourner liste tables (vide initial)
Étape 8 — Premier projet
Studio → SQL editor → CREATE TABLE products :
CREATE TABLE products (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name text NOT NULL,
price integer NOT NULL,
created_at timestamptz DEFAULT now()
);
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public read" ON products FOR SELECT USING (true);
Étape 9 — Test depuis client
// JavaScript
import { createClient } from '@supabase/supabase-js';
const supabase = createClient('https://api.votre-app.com', 'ANON_KEY');
const { data } = await supabase.from('products').select('*');
Étape 10 — Sauvegardes
# Cron quotidien
docker exec supabase-db pg_dump -U postgres postgres | gzip > /tmp/sb.gz
restic backup /tmp/sb.gz /var/lib/docker/volumes/supabase_storage
rm /tmp/sb.gz
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Studio 502 | Postgres pas prêt | Wait 60s + restart Studio |
| JWT invalid | ANON_KEY mal signée | Régénérer avec JWT_SECRET correct |
| Auth email non reçu | SMTP pas testé | GoTrue logs : docker logs supabase-auth |
| RLS bloque tout | Pas de policy | Créer policy pour role anon |
| Storage upload 403 | Bucket policy manquante | INSERT policy authenticated |
| OOM | RAM insuffisante | CCX13 minimum, CCX23 production sérieuse |
Considérations propres à l’écosystème sous-régional
Trois précisions. Hetzner Falkenstein : 95-130 ms vers Afrique Ouest acceptable. SDK mobile : Supabase iOS/Android natifs, optimisés cellular. Backup obligatoire : pg_dump 6h fréquence + restic vers B2.
Tutoriels frères
FAQ
CCX13 vs CCX23 ? CCX13 dev/staging. CCX23 production sérieuse.
Mises à jour ? docker compose pull && docker compose up -d. Migrations auto.
Multi-projets ? Une instance = un projet. Plusieurs Supabase pour multi-tenancy.
Coolify template ? Pas officiel. docker-compose.yml direct recommandé.
Storage S3 externe ? Oui. STORAGE_BACKEND=s3 + AWS_* vars.
Sur le même thème
- 🔝 guide général : guide pratique Supabase 2026
- Documentation : supabase.com/docs/self-hosting/docker
Hébergement recommandé pour les lecteurs
Si vous n’avez pas encore d’hébergeur, Hostinger est celui que nous utilisons et que nous recommandons après plusieurs années d’usage.
Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.
Étape 1 — Préparer le VPS Hetzner avant Coolify
Avant de penser à Supabase, il faut une base saine. À Dakar comme à Abidjan, beaucoup de projets se cassent les dents parce que le VPS est mal préparé : pas de swap, SSH ouvert au monde, pas de pare-feu. On commence donc par durcir un Hetzner CX22 (Ubuntu 24.04 LTS), facturé environ 4,51 EUR/mois soit ~2 960 FCFA, parfaitement suffisant pour une stack Supabase + Coolify de PME.
Connectez-vous en root via SSH puis créez un utilisateur dédié et activez l’authentification par clé. Le mot de passe root sert uniquement au premier accès.
adduser deploy
usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh
Si la dernière commande renvoie le prompt sans message d’erreur, le service est rechargé. Reconnectez-vous immédiatement avec ssh deploy@IP dans une autre fenêtre avant de fermer la session root, sinon vous risquez le verrouillage.
Étape 2 — Installer Coolify v4 en mode self-hosted
Coolify v4 joue ici le rôle de PaaS : il orchestre Docker, gère les certificats Let’s Encrypt et expose un panel web. L’installation officielle se fait en une commande, mais elle suppose que Docker n’est pas déjà installé. Sur Ubuntu 24.04, le script gère curl, Docker Engine 27.x et docker compose v2.
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash
Le script dure 4 à 7 minutes selon la latence vers l’Europe. À la fin, il affiche l’URL http://IP:8000 et un mot de passe d’initialisation. Notez-les. Pointez ensuite un sous-domaine (ex. coolify.exemple.sn) en A vers l’IP du VPS, puis dans le panel Settings > Instance, renseignez ce FQDN. Coolify déclenchera automatiquement l’émission d’un certificat TLS via Traefik.
Étape 3 — Créer un projet Supabase self-hosted
Dans Coolify, créez une nouvelle ressource de type « Service » et choisissez le template Supabase (officiel depuis Coolify 4.0.0-beta.350). Le template provisionne PostgreSQL 15, GoTrue, PostgREST, Realtime, Storage, le studio et Kong. Avant de cliquer Deploy, ouvrez l’onglet Environment et remplacez les secrets par défaut.
POSTGRES_PASSWORD=$(openssl rand -hex 24)
JWT_SECRET=$(openssl rand -hex 32)
ANON_KEY=<à générer via supabase/cli ou jwt.io>
SERVICE_ROLE_KEY=<idem>
DASHBOARD_PASSWORD=$(openssl rand -hex 16)
Ne réutilisez jamais les valeurs d’exemple du dépôt. Une fois sauvegardé, lancez Deploy. Coolify pull les images et démarre la stack en 3 à 5 minutes. Le studio devient accessible sur https://studio.exemple.sn protégé par Basic Auth.
Étape 4 — Configurer le stockage S3 pour les buckets
Le module Storage de Supabase peut utiliser le système de fichiers local, mais pour une PME à Cotonou ou Bamako qui sert des images de catalogue, mieux vaut un bucket S3-compatible. Hetzner Object Storage propose 1 To à 5,99 EUR/mois (~3 930 FCFA), région Falkenstein. Créez un bucket et une paire de clés, puis injectez-les dans la stack.
STORAGE_BACKEND=s3
GLOBAL_S3_BUCKET=supabase-assets
GLOBAL_S3_ENDPOINT=https://fsn1.your-objectstorage.com
GLOBAL_S3_PROTOCOL=https
GLOBAL_S3_FORCE_PATH_STYLE=true
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=fsn1
Redéployez la ressource. Vérifiez ensuite via Studio que la création d’un bucket renvoie bien un 200 et que le fichier apparaît dans la console Hetzner. Si vous voyez SignatureDoesNotMatch, c’est presque toujours un horodatage VPS désynchronisé : timedatectl set-ntp true règle le problème.
Étape 5 — Sauvegardes PostgreSQL automatisées
Sans backup, le projet n’est pas en production. Coolify embarque depuis la 4.0.0-beta.350 un planificateur de backups Postgres compressés. Activez-le sur la ressource supabase-db, fréquence quotidienne 02:00 UTC (donc 02:00 à Dakar, 03:00 à Cotonou), rétention 14 jours, destination Hetzner Object Storage.
Pour valider la sauvegarde, attendez la première exécution puis téléchargez le dump et restaurez-le sur une base jetable. Une sauvegarde non testée n’existe pas.
psql "postgresql://postgres:PWD@localhost:5432/restore_test" < backup.sql
psql "postgresql://postgres:PWD@localhost:5432/restore_test" -c "SELECT count(*) FROM auth.users;"
Si le compte d’utilisateurs correspond à la production, la chaîne de backup est validée. Documentez la procédure dans votre runbook interne.
Étape 6 — Exposer l’API publique avec un domaine et CORS
L’API REST PostgREST écoute par défaut sur /rest/v1/ via Kong. Coolify s’occupe du certificat. Côté CORS, ajoutez votre domaine front (par exemple https://app.exemple.sn) dans API_EXTERNAL_URL et SUPABASE_PUBLIC_URL, sinon le navigateur bloquera les appels depuis votre application Next.js ou Flutter Web.
Pour limiter la surface d’attaque, ajoutez une règle Kong de rate limiting : 60 requêtes par minute par IP suffisent à un MVP. Vous éditez volumes/api/kong.yml et redéployez.
Étape 7 — Connecter une application Next.js depuis Abidjan
Dans votre application, installez le SDK officiel et utilisez l’ANON_KEY côté client, jamais le SERVICE_ROLE_KEY. Ce dernier doit rester serveur uniquement.
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
Activez Row Level Security sur chaque table dès la création. Sans RLS, la clé anonyme expose toute la base au monde entier — c’est la première cause de fuite de données sur les projets Supabase self-hosted.
Étape 8 — Monitoring, mises à jour et coûts mensuels
Activez les notifications Coolify vers un webhook Discord ou un email pour être alerté des échecs de déploiement et des fins de certificats. Pour les mises à jour, l’équipe Supabase publie une nouvelle version de la stack toutes les 2 à 3 semaines. Le bouton « Redeploy » dans Coolify suffit, mais relisez le changelog pour les migrations SQL non rétro-compatibles.
Coût mensuel typique pour une PME ouest-africaine : VPS Hetzner CX22 ~2 960 FCFA, Object Storage 1 To ~3 930 FCFA, domaine .sn ~16 400 FCFA/an. Soit environ 8 250 FCFA par mois pour une stack complète, à comparer aux ~16 400 FCFA/mois minimum d’un Supabase Pro hébergé. Le retour sur investissement est immédiat dès qu’on dépasse 500 Mo de base ou 2 Go de stockage.
Pour approfondir, consultez aussi notre guide sur les headers de sécurité Caddy si vous préférez Caddy à Traefik, et notre article sur Cloudflare gratuit pour PME africaines pour mettre votre Supabase derrière un CDN performant.
Étape 9 — Migrer une base existante vers Supabase self-hosted
Beaucoup de PME à Dakar partent d’un PostgreSQL existant hébergé chez OVH ou Scaleway. La migration vers la stack Supabase Coolify se fait en trois temps : export, import, vérification. On suppose une base source de 500 Mo à 5 Go, taille typique d’un ERP de PME.
Sur la machine source, exportez avec pg_dump en format custom, plus rapide à restaurer et compressible.
pg_dump -Fc -h source.exemple.com -U app -d production -f prod.dump --no-owner --no-acl
scp prod.dump deploy@vps:/home/deploy/
Le flag --no-owner évite les erreurs de privilèges, car les rôles diffèrent entre l’ancienne base et Supabase. Une fois transféré, restaurez dans le conteneur PostgreSQL géré par Coolify.
docker exec -i supabase-db pg_restore -U postgres -d postgres --no-owner --role=postgres < prod.dump
Ouvrez ensuite le Studio, vérifiez que vos tables apparaissent dans le schéma public, puis activez RLS table par table. Pour les tables techniques internes (logs, file d’attente), gardez RLS désactivée et restreignez l’accès via le SERVICE_ROLE_KEY côté serveur.
Étape 10 — Edge Functions Deno pour la logique métier
La stack inclut edge-runtime, un runtime Deno qui exécute vos fonctions serverless localement, sans dépendre de Vercel ou Netlify. C’est utile pour traiter les webhooks Mixx by Yas (ex-Free Money), qui exigent une réponse en moins de 5 secondes.
Créez une fonction mixx-webhook à la racine du dépôt :
import { serve } from 'https://deno.land/std@0.208.0/http/server.ts'
serve(async (req) => {
const body = await req.json()
if (body.status === 'SUCCESS') {
// enregistrer la transaction côté DB via PostgREST
await fetch(`${Deno.env.get('SUPABASE_URL')}/rest/v1/payments`, {
method: 'POST',
headers: {
apikey: Deno.env.get('SERVICE_ROLE_KEY')!,
'Content-Type': 'application/json'
},
body: JSON.stringify({ ref: body.transactionId, amount_fcfa: body.amount })
})
}
return new Response('OK', { status: 200 })
})
Déployez via le menu Functions du Studio. L’URL publique est https://api.exemple.sn/functions/v1/mixx-webhook : transmettez-la à votre prestataire de paiement. Surveillez les logs en temps réel dans Coolify pour confirmer que chaque appel renvoie bien 200 OK.
Étape 11 — Limiter la facture en sortie réseau
Hetzner facture le trafic sortant au-delà de 20 To par mois sur un CX22 (0,001 EUR/Go au-delà). Pour un MVP ouest-africain, vous êtes très loin du seuil, mais surveillez tout de même via la commande suivante exécutée chaque semaine :
vnstat -m
Si vnstat n’est pas installé : apt install -y vnstat && systemctl enable --now vnstat. La sortie affiche le trafic mensuel ventilé. Au-delà de 5 To, envisagez de placer Supabase derrière Cloudflare gratuit pour mettre en cache les assets statiques du Storage et économiser ~70 % de bande passante.
Étape 12 — Plan de reprise après incident
Documentez un runbook précis : qui restaure, depuis quel backup, dans quel ordre. À Bamako comme à Cotonou, les coupures électriques peuvent provoquer un arrêt brutal. Hetzner garantit un SLA de 99,9 % mais votre équipe doit savoir réagir à un crash. Procédure type : 1) snapshot Hetzner du disque (gratuit, 5 minutes), 2) restauration du dump le plus récent depuis Object Storage, 3) re-déploiement de la stack Coolify, 4) test de bout en bout avec un compte utilisateur de référence.
Faites un exercice de restauration tous les trimestres avec un VPS jetable facturé à l’heure (~0,007 EUR soit ~5 FCFA pour 90 minutes de test). Cet investissement minime vous évitera la panique le jour d’un vrai incident en production.
Étape 13 — Ressources officielles à suivre
Trois sources à mettre en favoris pour rester à jour : le dépôt GitHub supabase/supabase et son onglet Releases, le canal Discord Coolify (réactivité en quelques heures), et la newsletter Hetzner Status pour les fenêtres de maintenance Falkenstein. Abonnez-vous au flux RSS des releases Supabase et déclenchez une notification dans votre messagerie d’équipe à chaque nouvelle version mineure : c’est souvent là que se cachent les correctifs de sécurité critiques.