Dépannage
Les erreurs que vous pouvez rencontrer en installant le restaurant, leur cause et comment les corriger.
Pour le pack Full Stack
Docker n'est pas lancé
failed to connect to the docker API at unix:///…/docker.sock; check if the path is correct and if the daemon is runningLes anciennes versions de Docker affichent plutôt « Cannot connect to the Docker daemon ». Dans les deux cas, le moteur Docker n'est pas démarré.
Ouvrez Docker Desktop
Lancez Docker Desktop et attendez qu'il indique que le moteur est en marche. Sous Linux, démarrez le service :
sudo systemctl start docker.Vérifiez que Docker répond
Terminaldocker infoRésultat attendu: Une section Server s'affiche au lieu d'une erreur.
Relancez votre commande de démarrage
docker compose up --buildpour le pack Full Stack, ou vos commandesdocker buildetdocker runpour une application seule.
Un port est déjà utilisé
ports are not available: exposing port TCP 0.0.0.0:3031 … bind: address already in use
Bind for 0.0.0.0:3031 failed: port is already allocated
Error: listen EADDRINUSE: address already in use :::3031Les deux premières lignes viennent de Docker, la dernière de yarn dev. Un autre programme écoute déjà sur 3030, 3031 ou 8000 : souvent une exécution précédente du restaurant, ou le serveur de développement d'un autre projet.
Trouvez ce qui occupe le port
Sous macOS ou Linux, avec le port indiqué dans le message :
Terminallsof -i :3031Sous Windows, dans PowerShell :
Terminalnetstat -ano | findstr :3031Arrêtez-le
Fermez ce programme, ou arrêtez l'exécution précédente : Ctrl+C dans son terminal,
docker compose downdans son dossier, oudocker stoppour un conteneur démarré avecdocker run. Puis redémarrez le restaurant.Ou lancez le restaurant sur d'autres ports
Avec le pack complet sous Docker, créez un fichier nommé
.envdans le dossierfood-studio-full-stack, à côté dedocker-compose.yml, avec le port dont vous avez besoin.SITE_PORTdéplace le site,ADMIN_PORTle tableau de bord etAPI_PORTl'API ; les adresses utilisées par les applications,CORS_ORIGINcompris, suivent d'elles-mêmes.food-studio-full-stack/.envADMIN_PORT=3041Relancez ensuite la même commande. Un démarrage qui a échoué reprend là où il s'était arrêté :
Terminaldansfood-studio-full-stackdocker compose up --buildRésultat attendu: L'application répond sur son nouveau port, ici localhost:3041Local.
Pour une application seule démarrée avec docker run, changez le nombre à gauche de -p, par exemple -p 3041:3031, et ajoutez la nouvelle adresse au CORS_ORIGIN de l'API. Sans Docker, les ports sont fixés dans les fichiers .env : pour déplacer l'API, changez ensemble PORT dans le .env de l'API et NEXT_PUBLIC_API_BASE_URL dans les deux frontends ; pour déplacer un frontend, ajoutez sa nouvelle adresse à CORS_ORIGIN.
Le build Docker échoue
Le premier build télécharge les images de base et toutes les dépendances, puis construit les images. Quand quelque chose bloque, il s'arrête avec « failed to solve » et l'étape qui a échoué.
- Pas de connexion ou délai dépassé : le build a besoin d'un accès à internet. Relancez la commande une fois en ligne ; les étapes terminées sont en cache.
- No space left on device : libérez de l'espace dans Docker Desktop, ou vérifiez ce que Docker occupe avec
docker system df. - L'échec survient toujours à la même étape : reconstruisez sans le cache, puis démarrez.
food-studio-full-stackdocker compose build --no-cache
docker compose upPour un pack à application unique, ajoutez --no-cache à votre commande docker build.
Un premier démarrage qui semble bloqué est généralement encore en train de charger le restaurant de démonstration. Le site et le tableau de bord ne démarrent qu'une fois que l'API se déclare en bonne santé.
Yarn indique la version 1.22
This project's package.json defines "packageManager": "yarn@4…". However the current global version of Yarn is 1.22…Chaque application fixe Yarn 4 via Corepack. Ce message signifie que Corepack n'est pas encore activé, et que c'est donc l'ancien Yarn global qui a répondu.
corepack enablePuis relancez yarn install. Si votre Node.js n'a pas Corepack, installez-le d'abord avec npm install -g corepack.
Une installation ou un démarrage échoue avec une version ancienne de Node.js
Chaque application déclare Node.js 24 ou plus récent, et son image Docker tourne sur Node.js 24. Yarn ne bloque pas lui-même une version plus ancienne, donc un Node.js ancien se manifeste plus tard : une installation qui n'arrive pas à construire un paquet, ou une application qui s'arrête au démarrage.
node -vS'il affiche une version inférieure à 24, installez Node.js 24 ou plus récent, relancez corepack enable, puis supprimez le dossier node_modules de l'application et relancez yarn install. Avec Docker, rien de tout cela ne s'applique : les images apportent leur propre Node.js.
Le site répond 500 en développement
La première fois que yarn dev ouvre une page, Next.js télécharge les polices Google du site. Sans connexion internet, ou avec fonts.googleapis.com bloqué, chaque page répond 500 et la console du navigateur nomme un fichier de police, comme ibm_plex_sans_arabic.
Connectez-vous, puis rechargez la page. yarn build et la build Docker téléchargent les polices une seule fois, au moment de la build : un site construit n'en a plus besoin ensuite.
L'API s'arrête avant de démarrer
The API cannot start: JWT_SECRET is not set. Set it in back-end/.env to the output of: …
The API cannot start: JWT_SECRET is still the example value from .env.example, so anyone can sign a token for any account. …
The API cannot start: CORS_ORIGIN is not set. List the storefront and admin dashboard origins, comma separated, …L'API vérifie ses paramètres avant de démarrer et affiche une ligne par problème. Les causes :
- Il n'y a pas de fichier `.env`, ou `JWT_SECRET` est vide. Créez le fichier dans le dossier de l'API avec
cp .env.example .env. - `JWT_SECRET` a encore la valeur d'exemple avec `NODE_ENV=production`. N'importe qui pourrait signer un jeton avec l'exemple public : un démarrage en production le refuse donc. Générez votre propre secret.
- `CORS_ORIGIN` est vide avec `NODE_ENV=production`. Indiquez l'adresse du site et celle du tableau de bord, séparées par une virgule.
Générez un secret avec :
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"Avec Docker, vous n'en avez pas besoin : un conteneur sans JWT_SECRET propre, ou avec celui de l'exemple, génère un secret et le conserve dans le volume de données.
Le menu est vide et personne ne peut se connecter
→ No database at /data/database.sqlite. Creating the tables, no data (set SEED_DEMO_DATA=true for the demo).La base de données a été créée avec les tables seulement. Cela arrive quand le conteneur de l'API démarre sur un nouveau volume sans SEED_DEMO_DATA=true, quand le pack complet tourne avec SEED_DEMO_DATA=false dans le .env à côté de docker-compose.yml, ou sans Docker quand yarn db:sync a été lancé au lieu de yarn seed. Il n'y a ni menu, ni cuisine, ni compte pour se connecter.
- Sans Docker : lancez
yarn seeddans le dossier de l'API. Il ajoute le restaurant de démonstration et ses comptes aux tables existantes. - Pack complet sous Docker : retirez
SEED_DEMO_DATA=falsedu.env, puis lancezdocker compose down -vetdocker compose up. Le volume de données est recréé avec le restaurant de démonstration. - Conteneur de l'API : supprimez le conteneur et son volume, puis relancez-le avec
-e SEED_DEMO_DATA=true, comme dans Repartir de données de démonstration neuves, plus bas.
Le conteneur ne recharge jamais les données de démonstration dans une base existante, quelle que soit la valeur de SEED_DEMO_DATA : la variable ne compte donc que sur un nouveau volume.
La connexion échoue
- Vérifiez le compte et l'application. Le personnel se connecte au tableau de bord sur le port
3031:owner@foodstudio.exampleavecFoodDemo2026!. Les clients se connectent au site sur le port3030:sam@foodstudio.exampleavecFoodDemo2026!. Un compte client ne peut pas ouvrir le tableau de bord, et un compte du personnel ne peut pas se connecter sur le site. - Le tableau de bord affiche « We could not sign you in. Check your email and password, then try again. » pour un mauvais mot de passe, un e-mail inconnu ou une base de données sans compte. Après trop de tentatives échouées, il vous demande plutôt de patienter quelques minutes. Vérifiez les points ci-dessous l'un après l'autre.
- La base de données n'a aucun compte quand elle a été créée avec
SEED_DEMO_DATA=false. Voir Le menu est vide et personne ne peut se connecter, plus haut. - Dix échecs de connexion depuis une même adresse en 15 minutes bloquent ce formulaire de connexion pour cette adresse. L'API répond
429jusqu'à ce que le plus ancien échec date de 15 minutes. Patientez, ou redémarrez l'API : le compteur est gardé en mémoire. - Vous avez changé le mot de passe du propriétaire et ne l'avez plus : repartez de données de démonstration neuves, ci-dessous.
La connexion échoue
- Vérifiez le compte et la route. Le personnel se connecte sur
POST /api/auth/login(le propriétaire estowner@foodstudio.exampleavecFoodDemo2026!) ; les clients surPOST /api/auth/customer/login(sam@foodstudio.exampleavecFoodDemo2026!). Une connexion échouée répond401avec le même message, que l'e-mail ou le mot de passe soit faux. - Aucun compte ne fonctionne : la base de données a été créée sans le restaurant de démonstration. Lancez
yarn seed, ou démarrez le conteneur avec-e SEED_DEMO_DATA=truesur un nouveau volume. - Une réponse `429` signifie qu'une adresse a échoué 10 connexions sur cette route en 15 minutes. Elle disparaît quand le plus ancien échec date de 15 minutes, ou quand l'API redémarre.
RATE_LIMIT_LOGINchange ce nombre.
La connexion échoue
Votre application se connecte via l'API du template, le compte doit donc exister dans cette API. Sur une API avec les données de démonstration, le personnel se connecte au tableau de bord avec owner@foodstudio.example et les clients au site avec sam@foodstudio.example, tous deux avec FoodDemo2026!. Si aucun compte ne fonctionne, soit l'API a été démarrée sans ses données de démonstration (lancez yarn seed dans son dossier, ou démarrez son conteneur sur un nouveau volume avec -e SEED_DEMO_DATA=true), soit l'application n'arrive pas à joindre l'API : voir le problème suivant.
Les pages restent vides et le navigateur signale une erreur CORS
Access to fetch at 'http://localhost:8000/api/…' from origin 'http://localhost:3041' has been blocked by CORS policyLa console du navigateur affiche cette ligne quand un frontend tourne sur une adresse que l'API n'accepte pas. L'API ne répond aux navigateurs que depuis les adresses de CORS_ORIGIN, qui vaut par défaut http://localhost:3030 et http://localhost:3031. Un site ou un tableau de bord déplacé sur un autre port, ou servi sur votre propre domaine, est refusé tant qu'il n'est pas dans la liste.
CORS_ORIGIN=http://localhost:3030,http://localhost:3041
FRONTEND_URL=http://localhost:3041- Écrivez chaque adresse exactement comme le navigateur l'affiche, avec le schéma et le port et sans barre oblique finale, séparées par des virgules. Puis redémarrez l'API.
FRONTEND_URLest l'adresse du tableau de bord, depuis laquelle se connectent ses notifications en direct, etSTOREFRONT_URLcelle du site, vers laquelle un lien de paiement ou de réinitialisation du mot de passe envoie le client. Déplacez-les en même temps que l'application.- Pour un conteneur de l'API, passez les mêmes valeurs avec
-e, par exemple-e CORS_ORIGIN=http://localhost:3030,http://localhost:3041. - Avec le pack complet sous Docker, vous ne les modifiez pas :
SITE_PORT,ADMIN_PORT,SITE_URLetADMIN_URLdans le.envà côté dedocker-compose.ymlles définissent. - Un frontend qui ne peut pas joindre l'API du tout, parce qu'elle est arrêtée ou à une autre adresse, échoue de la même façon, sans la ligne CORS. Vérifiez que localhost:8000/api/healthLocal répond, et que le
NEXT_PUBLIC_API_BASE_URLdu frontend désigne bien cette API.
Les photos des plats ne s'affichent pas
Les photos de démonstration sont servies par l'API sous /media/food-studio/…, et les données de démonstration enregistrent l'adresse complète de chaque photo à partir de PUBLIC_MEDIA_URL, qui vaut par défaut http://localhost:8000/media. Une photo ne s'affiche pas quand cette adresse ne mène pas à l'API depuis le navigateur.
- L'API tourne sur un autre port ou un autre domaine. Définissez
PUBLIC_MEDIA_URLavec l'adresse publique de l'API suivie de/media, par exemple-e PUBLIC_MEDIA_URL=http://localhost:8010/mediaavecdocker run -p 8010:8000. Avec le pack complet sous Docker,API_PORTetAPI_URLla définissent pour vous. - L'API a changé d'adresse après le premier démarrage. Redémarrez l'API avec
PUBLIC_MEDIA_URLdéfini sur la nouvelle adresse (avec Docker Compose,API_PORTouAPI_URLs'en charge). Au démarrage, elle fait pointer chaque photo enregistrée sous/media/food-studio/et/media/uploads/vers cette adresse, et son journal indique combien elle en a modifié. - Les fichiers envoyés vers un bucket ne s'affichent pas.
R2_PUBLIC_URLdoit être l'adresse publique du bucket, et le bucket doit autoriser la lecture publique. - Les photos s'affichent, mais lentement et en taille réelle. Les frontends ne redimensionnent que les photos venant de l'hôte https indiqué dans
NEXT_PUBLIC_MEDIA_HOSTNAME(avec Docker Compose,MEDIA_HOSTNAME), écrit comme hôte seul, par exemplepub-1234.r2.dev. Toute autre photo est affichée telle quelle. Reconstruisez le frontend après l'avoir modifié.
Une modification du .env d'un frontend n'a aucun effet
Chaque valeur NEXT_PUBLIC_* est compilée dans le JavaScript chargé par le navigateur au moment du build de l'application. Modifier le fichier ne change rien tant que l'application n'est pas reconstruite.
| Comment vous la lancez | Après avoir modifié une valeur |
|---|---|
yarn dev | Arrêtez-la et relancez yarn dev. |
yarn build et yarn start | Relancez yarn build, puis yarn start. |
| Docker Compose | Lancez docker compose up --build. Définissez la valeur dans le .env à côté de docker-compose.yml, pas dans le dossier de l'application. |
docker build pour une seule application | Reconstruisez l'image avec la valeur passée en --build-arg. |
Les nouvelles commandes n'apparaissent pas d'elles-mêmes dans le tableau de bord
La cloche du tableau de bord et ses mises à jour de commandes en direct utilisent un WebSocket vers l'API. Le tableau de bord se connecte à NEXT_PUBLIC_WEBSOCKET_BASE_URL, l'adresse de l'API sans /api, et l'API n'accepte la connexion que depuis FRONTEND_URL, l'adresse du tableau de bord lui-même.
- Faites correspondre les deux à l'endroit où les applications tournent réellement, puis redémarrez l'API et reconstruisez le tableau de bord.
- Si
FRONTEND_URLn'est pas défini, seulhttp://localhost:3031est accepté : sur toute autre adresse, la connexion en direct est refusée. - Un rechargement affiche toujours les dernières commandes : seules les mises à jour en direct dépendent de la connexion.
Une fonctionnalité indique qu'elle n'est pas connectée
Les paiements par carte et PayPal, les envois vers un bucket, l'e-mail de réinitialisation du mot de passe, l'assistant IA et le studio IA ne s'activent que lorsque leurs variables sont définies dans le .env de l'API. Dans .env.example, elles sont en commentaire : un fichier copié démarre donc proprement et chacune de ces fonctionnalités reste désactivée.
- Retirez le
#devant la ligne et collez votre vraie valeur à la place de l'exemple. - Redémarrez l'API après avoir modifié son
.env. Avec Docker Compose, l'API lit aussiback-end/.env, donc relancerdocker compose upsuffit ; un conteneur de l'API seul a besoin de--env-file .envdans sondocker run. - L'e-mail de réinitialisation du mot de passe nécessite à la fois
RESEND_API_KEYetMAIL_FROM. Sans eux, « Forgot password » répond toujours comme d'habitude, et le journal indique « Mail is not configured: set RESEND_API_KEY and MAIL_FROM to send password reset messages. »
Une commande payée reste impayée
Une commande n'est considérée comme payée qu'une fois que l'API a confirmé le paiement auprès de Stripe ou PayPal, au retour du client ou à l'arrivée du webhook du prestataire. Si une commande reste impayée alors que le client a payé :
- Le client n'est jamais revenu vers l'API. Le prestataire renvoie le navigateur vers
API_PUBLIC_URL, qui vaut par défauthttp://localhost:8000. Sur votre propre domaine, définissez-le avec l'adresse publique de l'API. - Le webhook n'est pas configuré. Faites-le pointer vers l'adresse de votre API suivie de
/api/payments/webhooks/stripeou/api/payments/webhooks/paypal, et définissezSTRIPE_WEBHOOK_SECRETouPAYPAL_WEBHOOK_ID. Un appel non signé ou modifié est refusé avec401. - Le client a quitté la page de paiement. Une commande pour laquelle personne n'est revenu est vérifiée auprès du prestataire, au bout de 35 minutes pour Stripe et de 3 heures pour PayPal, puis annulée si elle n'a pas été payée, ce qui restitue son stock et ses points.
Le paiement indique que la cuisine est fermée ou que l'adresse est hors zone
This kitchen is closed. Choose another kitchen.
Delivery is unavailable here. Try pickup.- Fermée. Une cuisine ne prend des commandes que pendant ses horaires, dans son propre fuseau horaire. Avec l'horloge de service sur Real, en dehors de ces horaires, le paiement refuse aussi bien la livraison que le retrait sur place. Modifiez les horaires dans Settings, Restaurant, ou essayez une autre cuisine.
- Hors zone. La livraison ne se fait que vers les codes postaux qu'une cuisine indique. Les cuisines de démonstration livrent à des codes postaux comme
10001et10002. Ajoutez vos propres codes postaux à chaque cuisine dans Settings, Restaurant. - Sous le minimum. Une commande en livraison doit atteindre au moins le minimum de livraison en nourriture,
$10.00dans les paramètres de démonstration.
Chaque visiteur reçoit « Too many attempts » derrière un proxy
Les formulaires publics sont limités par adresse de visiteur : commandes, sessions de paiement, suivi, inscription, formulaire de contact, réinitialisations du mot de passe et connexions échouées. Derrière un reverse proxy, tous les visiteurs peuvent sembler venir de l'unique adresse du proxy et partager un seul quota. Indiquez à l'API combien de proxys se trouvent devant elle :
TRUST_PROXY=1Les variables RATE_LIMIT_* de .env.example modifient chaque limite. Les compteurs sont gardés dans la mémoire de l'API, donc un redémarrage les remet à zéro.
MySQL refuse de démarrer ou de remplir la base
L'API crée ses tables dans une base de données qui existe déjà ; elle ne crée pas la base elle-même. Créez d'abord une base vide, indiquez son nom dans DB_DATABASE du .env de l'API, puis lancez yarn seed (ou yarn db:sync pour les tables sans données de démonstration).
- Vérifiez les cinq valeurs de connexion
DB_*et queDB_TYPE=mysql. - Avec
NODE_ENV=production, l'API en fonctionnement ne crée jamais de tables : l'une de ces commandes doit donc être lancée avant le premier démarrage (yarn seed:prodouyarn db:sync:prodaprèsyarn build). - L'image Docker ne crée la base de données d'elle-même que sur SQLite. Sur MySQL, lancez vous-même une fois la commande des données de démonstration ou celle du schéma.
Le conteneur de l'API ne trouve pas son point d'entrée
exec /usr/local/bin/docker-entrypoint.sh: no such file or directoryLe script a des fins de ligne Windows, qu'un éditeur ou Git sous Windows peut ajouter. Le Dockerfile de l'API fourni les retire pendant le build, donc cela n'apparaît qu'avec une image construite à partir d'un Dockerfile modifié. Gardez sa ligne sed -i 's/\r$//', ou enregistrez le script avec des fins de ligne LF, puis reconstruisez sans le cache.
Le dossier ne correspond pas
Exécutez les commandes dans le dossier où le ZIP est extrait. Si la commande unzip est absente, extrayez-le plutôt avec votre gestionnaire de fichiers ; certains outils ajoutent un dossier supplémentaire portant le nom du ZIP : placez-vous alors dans le dossier intérieur.
| Pack | Dossier | Contenu |
|---|---|---|
| Full Stack | food-studio-full-stack | admin-dashboard, back-end, storefront, docker-compose.yml |
| Site de commande | food-studio-website | Dockerfile, package.json, .env.example |
| Tableau de bord du personnel | food-studio-staff-dashboard | Dockerfile, package.json, .env.example |
| API backend | food-studio-backend | Dockerfile, package.json, .env.example |
Repartir de données de démonstration neuves
Cette opération supprime vos données
Tout ce que vous avez créé en local est supprimé, et le restaurant de démonstration est rechargé.
Avec le pack complet sous Docker, depuis le dossier food-studio-full-stack :
food-studio-full-stackdocker compose down -v
docker compose upAvec un conteneur API seul, supprimez d'abord le conteneur (docker ps -a l'affiche, docker rm -f suivi de son identifiant le supprime), puis supprimez le volume et relancez-le :
docker volume rm foodstudio-data
docker run -p 8000:8000 -v foodstudio-data:/data -e SEED_DEMO_DATA=true foodstudio-apiSans Docker, arrêtez l'API, puis dans son dossier :
rm -f database.sqlite* && yarn seedDans PowerShell :
Remove-Item database.sqlite*; yarn seedRelancer yarn seed sur une base que vous conservez n'est pas une réinitialisation : cela n'ajoute que ce qui manque et ne change jamais une valeur que vous avez modifiée. yarn db:reset supprime toutes les tables, sur SQLite comme sur MySQL ; lancez yarn seed ensuite.