Aller à l'article
Aniq-UI

KinoraDépannage

Dépannage

Les erreurs que vous pouvez rencontrer en installant Kinora, la cause de chacune et comment la corriger.

Pour le pack Full Stack

Docker n'est pas lancé

Ce que vous voyez
failed to connect to the docker API at unix:///…/docker.sock; check if the path is correct and if the daemon is running

Les 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é.

  1. 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.

  2. Vérifiez que Docker répond

    Terminal
    docker info

    Résultat attendu: Une section Server s'affiche au lieu d'une erreur.

  3. Relancez votre commande de démarrage

    docker compose up --build pour le pack Full Stack, ou vos commandes docker build et docker run pour une application seule.

Un port est déjà utilisé

Ce que vous voyez
ports are not available: exposing port TCP 0.0.0.0:3030 … bind: address already in use
Error: listen EADDRINUSE: address already in use :::3030

La première ligne vient de Docker, la seconde de yarn dev. Un autre programme écoute déjà sur 3030 ou 8000 : souvent un lancement précédent de Kinora, ou le serveur de développement d'un autre projet.

  1. Trouvez ce qui occupe le port

    Sous macOS ou Linux :

    Terminal
    lsof -i :3030

    Sous Windows, dans PowerShell :

    Terminal
    netstat -ano | findstr :3030
  2. Arrêtez-le

    Fermez ce programme, ou arrêtez le lancement précédent : Ctrl+C dans son terminal, docker compose down dans son dossier, ou docker stop pour un conteneur démarré avec docker run. Puis redémarrez Kinora.

  3. Ou lancer Kinora sur d'autres ports

    Avec la version complète dans Docker, créez un fichier nommé .env dans le dossier kinora-fitness-full-stack, à côté de docker-compose.yml, avec le port voulu. DASHBOARD_PORT déplace le tableau de bord et API_PORT l'API ; les adresses qu'utilisent les applications suivent d'elles-mêmes.

    kinora-fitness-full-stack/.env
    DASHBOARD_PORT=3040

    Puis relancez la même commande. Après un démarrage raté, elle reprend là où elle s'était arrêtée :

    Terminaldans kinora-fitness-full-stack
    docker compose up --build

    Résultat attendu: Le tableau de bord répond sur son nouveau port, ici localhost:3040Local.

Sans Docker, les ports se règlent dans les fichiers .env. Pour y déplacer l'API, changez ensemble PORT dans back-end/.env et les deux adresses de l'API dans dashboard/.env. Pour déplacer le tableau de bord, changez PORT dans dashboard/.env et CORS_ORIGIN dans back-end/.env. Avec Docker, utilisez plutôt API_PORT et DASHBOARD_PORT. Pour une application seule démarrée avec docker run, changez le nombre à gauche de -p.

Configuration

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.
Terminaldans kinora-fitness-full-stack
docker compose build --no-cache
docker compose up

Pour 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 d'insérer les données de démonstration. Le tableau de bord ne démarre qu'une fois que l'API se déclare en bonne santé.

Yarn indique la version 1.22

Ce que vous voyez
This project's package.json defines "packageManager": "yarn@4.8.1…". 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.

Terminal
corepack enable

Puis relancez yarn install. Si votre Node.js n'a pas Corepack, installez-le d'abord avec npm install -g corepack.

L'API s'arrête avant de démarrer

Ce que vous voyez
✖ 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, …
✖ The API cannot start: CORS_ORIGIN is not set. List the dashboard origin (comma separated if there are several), …

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 back-end/ 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-y l'adresse du tableau de bord, séparées par des virgules s'il y en a plusieurs.

Générez un secret avec :

Terminal
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 health check répond 503

Ce que vous voyez
{"status":"unavailable"}
The database has no tables yet. Run `yarn seed` in back-end/, then restart the API.

/api/health répond 503 tant que la base de données ne répond pas et ne contient pas ses tables. La seconde ligne est ce qu'affiche le journal de l'API au démarrage quand les tables manquent.

  • Sans Docker, en développement : exécutez yarn seed dans back-end/ (tables et données de démonstration), ou yarn db:sync (tables seules), puis redémarrez l'API.
  • Avec `NODE_ENV=production` : l'API ne crée pas les tables d'elle-même. Exécutez une fois yarn db:sync:prod (tables vides) ou yarn seed:prod (avec les données de démonstration), après yarn build.
  • Avec Docker sur SQLite : le conteneur crée les tables de lui-même au premier démarrage. Sur MySQL, il ne le fait pas : son journal vous indique d'exécuter vous-même une fois node dist/database/sync-schema.js (tables) ou node dist/database/seeder.js (tables et données de démonstration).
  • « The database has no accounts, so nobody can sign in » signifie que les tables existent mais qu'aucun compte n'a jamais été ajouté : exécutez yarn seed dans back-end/.

MySQL refuse de démarrer ou de remplir la base

L'API crée ses tables dans une base de données existante ; elle ne crée pas la base elle-même. Créez d'abord une base de données vide, indiquez son nom dans DB_DATABASE de back-end/.env, puis exécutez yarn seed (ou yarn db:sync pour les tables sans données de démonstration).

  • Vérifiez les cinq valeurs de connexion DB_* et que DB_TYPE=mysql.
  • Avec NODE_ENV=production, l'API en marche ne crée jamais les tables : l'une de ces commandes s'exécute donc avant le premier démarrage, yarn db:sync:prod ou yarn seed:prod après yarn build.

La connexion échoue

  • Vérifiez le compte. Tout le monde se connecte sur le même formulaire, sur le port 3030 : le Head Coach est headcoach@example.com avec Coach@123, le membre member@example.com avec Member@123.
  • Consultez le journal de l'API. « The database has no accounts, so nobody can sign in » signifie que les données de démonstration n'ont jamais été ajoutées. Sans Docker, exécutez yarn seed dans back-end/. Avec Docker, le volume a été créé avec SEED_DEMO_DATA=false.
  • « The database has no tables yet » signifie que le schéma n'a jamais été créé : exécutez yarn seed dans back-end/ et redémarrez l'API.
  • Vous avez changé le mot de passe du Head Coach et ne l'avez plus : repartez de données de démonstration neuves, ci-dessous.
  • « That email and password combination didn't work. Please try again. » est la même réponse pour un e-mail inconnu et pour un mauvais mot de passe : vérifiez donc les deux.
  • « Too many attempts. Wait a minute and try again. » signifie qu'une même adresse a fait plus de 10 tentatives en une minute sur la route de connexion, d'inscription ou de suppression de compte. Attendez une minute et réessayez.

La connexion échoue

  • Consultez le journal de l'API. « The database has no accounts, so nobody can sign in » signifie que les données de démonstration n'ont jamais été ajoutées : exécutez yarn seed, ou démarrez le conteneur Docker avec -e SEED_DEMO_DATA=true sur un nouveau volume.
  • « The database has no tables yet » signifie que le schéma n'a jamais été créé : exécutez yarn seed et redémarrez l'API.
  • Vérifiez le compte. Tout le monde se connecte via POST /api/auth/login : le Head Coach est headcoach@example.com avec Coach@123, le membre member@example.com avec Member@123. Une connexion échouée répond 401 avec le même message, que ce soit l'e-mail ou le mot de passe qui soit faux.
  • Une réponse `429` signifie qu'une même adresse a fait plus de 10 tentatives en une minute sur la route de connexion, d'inscription ou de suppression de compte. L'en-tête Retry-After indique combien de secondes attendre.

La connexion échoue

Sur les données d'exemple, le mot de passe n'est pas vérifié, mais le formulaire demande quand même au moins 6 caractères. Un e-mail qui appartient à un compte d'exemple se connecte avec ce compte, et tout autre e-mail se connecte en tant que Head Coach. Une fois une API connectée, connectez-vous avec un compte qui y existe : le Head Coach de démonstration est headcoach@example.com avec Coach@123, et le membre de démonstration member@example.com avec Member@123.

Chaque visiteur reçoit « Too many attempts » derrière un proxy

La connexion, l'inscription et la suppression de compte autorisent 10 requêtes par minute, par adresse et par route, puis répondent 429. L'API ne lit l'adresse du visiteur dans X-Forwarded-For que si la requête vient d'un proxy sur une adresse privée, de bouclage ou de plateforme, comme dans Docker, sur Railway ou derrière un reverse proxy sur la même machine.

Quand votre proxy joint l'API depuis une adresse publique, chaque visiteur ressemble à ce seul proxy et tous partagent le même quota. Indiquez à l'API combien de proxies se trouvent devant elle :

back-end/.env
TRUST_PROXY=1

TRUST_PROXY=false ne lit jamais l'en-tête. Laissez-la non définie quand l'API est jointe directement ou via un proxy sur une adresse privée. Les compteurs vivent dans la mémoire de l'API : un redémarrage les remet donc à zéro.

Une mention « Sample data » apparaît

Ce que vous voyez
No API is connected (NEXT_PUBLIC_API_BASE_URL is empty), so the dashboard is running on built-in sample data: …

Le tableau de bord a été démarré ou construit sans NEXT_PUBLIC_API_BASE_URL : il répond donc à chaque requête avec des données d'exemple, dans le navigateur. Ce que vous modifiez est alors conservé dans le navigateur, pas dans la base de données.

  1. Donner au tableau de bord l'adresse de l'API

    Créez dashboard/.env à partir de .env.example s'il n'en a pas. NEXT_PUBLIC_API_BASE_URL doit être l'adresse de l'API avec /api, par exemple http://localhost:8000/api, et NEXT_PUBLIC_WEBSOCKET_BASE_URL le même serveur sans ce suffixe.

  2. Vérifiez que l'API répond

    Ouvrez localhost:8000/api/healthLocal. Il doit répondre {"status":"ok"}. Si l'adresse est définie mais que l'API ne répond pas, les pages ne peuvent pas charger leurs données : les données d'exemple ne prennent pas le relais.

  3. Redémarrer ou reconstruire le tableau de bord

    L'adresse est compilée dans l'application. Redémarrez yarn dev après l'avoir modifiée, relancez yarn build avant yarn start, ou avec Docker relancez docker compose up --build.

Une modification du .env du tableau de bord 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 lancezAprès avoir modifié une valeur
yarn devArrêtez-la et relancez yarn dev.
yarn build et yarn startRelancez yarn build, puis yarn start.
Docker ComposeExécutez docker compose up --build. Définissez API_URL, DASHBOARD_URL ou MEDIA_HOSTNAME dans le .env à côté de docker-compose.yml, pas dans le dossier du tableau de bord.
docker build pour le tableau de bordReconstruisez l'image avec la valeur passée en --build-arg.

Une fonctionnalité indique qu'elle n'est pas configurée

Les envois de fichiers et l'assistant IA ne s'activent que lorsque leurs clés sont dans back-end/.env. Une clé qui garde exactement sa valeur de .env.example compte comme non définie : un .env.example copié démarre donc proprement, et chacune de ces fonctionnalités se signale comme désactivée au lieu d'échouer à son premier appel.

  • Collez votre vraie clé à la place de la valeur d'exemple, pas à côté.
  • Redémarrez l'API après avoir modifié back-end/.env. Avec Docker Compose, l'API lit aussi ce fichier : relancer docker compose up suffit donc ; un conteneur API seul a besoin de --env-file .env dans son docker run.

Les envois de fichiers sont refusés

Ce que vous voyez
File storage is not configured on this server. Set the R2 variables in .env to enable uploads.

Les photos de profil, les photos de progression et les pièces jointes des messages vont dans un bucket Cloudflare R2 ou un autre bucket compatible S3, et un envoi répond 400 avec ce message tant que les cinq variables R2_* ne sont pas définies dans back-end/.env. Les données de démonstration n'ont besoin d'aucun bucket : leurs images sont des chemins /assets/images/… que le tableau de bord sert depuis son propre dossier public/.

Les requêtes sont bloquées sur vos propres domaines

Ce que vous voyez
Access to XMLHttpRequest at 'https://api.your-domain.com/api/…' from origin 'https://app.your-domain.com' has been blocked by CORS policy

L'API ne répond aux navigateurs que depuis les adresses de CORS_ORIGIN, et ses sockets en direct que depuis FRONTEND_URL quand il est défini (sinon depuis la même liste). Les deux pointent par défaut vers le tableau de bord local sur le port 3030 : sur votre propre domaine, ils doivent donc le nommer.

back-end/.env
CORS_ORIGIN=https://app.your-domain.com
FRONTEND_URL=https://app.your-domain.com

Écrivez chaque adresse exactement comme le navigateur l'affiche, avec https:// et sans barre oblique finale, puis redémarrez l'API. Avec Docker Compose, définissez plutôt DASHBOARD_URL et API_URL dans le .env à côté de docker-compose.yml et exécutez docker compose up --build : le fichier compose construit les deux valeurs à partir d'eux.

« Forgot password » n'envoie rien

Les pages de mot de passe oublié et de réinitialisation du tableau de bord ne sont que des écrans : aucune réinitialisation n'est envoyée et aucun mot de passe n'est modifié par leur biais. Elles appellent POST /api/auth/forgot-password et POST /api/auth/reset-password, que l'API du template n'a pas : avec l'API, le formulaire affiche donc une erreur. Avec les données d'exemple, le formulaire affiche sa confirmation, mais rien n'est envoyé non plus. Pour donner un nouveau mot de passe à un membre, un compte de l'équipe avec members.update le définit sur la page du membre, sous Salle. Une réinitialisation en libre-service demande ces deux routes et votre propre fournisseur d'e-mails.

Le conteneur de l'API ne trouve pas son point d'entrée

Ce que vous voyez
exec /usr/local/bin/docker-entrypoint.sh: no such file or directory

Le script a des fins de ligne Windows, qu'un éditeur ou Git sous Windows peut ajouter. Le back-end/Dockerfile livré les supprime pendant le build : ce problème n'apparaît donc 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.

Terminaldans kinora-fitness-full-stack
docker compose build --no-cache api
docker compose up

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.

PackDossierContenu
Full Stackkinora-fitness-full-stackback-end, dashboard, docker-compose.yml
Tableau de bordkinora-fitness-dashboardDockerfile, package.json, .env.example
Backendkinora-fitness-backendDockerfile, 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 les données de démonstration sont à nouveau insérées.

Avec Docker Compose, depuis le dossier kinora-fitness-full-stack :

Terminaldans kinora-fitness-full-stack
docker compose down -v
docker compose up

Avec 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 :

Terminaldans kinora-fitness-backend
docker volume rm kinora-data
docker run -p 8000:8000 -v kinora-data:/data -e SEED_DEMO_DATA=true kinora-api

Sans Docker, arrêtez l'API, puis dans son dossier :

Terminal
rm -f database.sqlite* && yarn seed

Dans PowerShell :

Terminal
Remove-Item database.sqlite*; yarn seed

Relancer yarn seed sur une base de données que vous conservez n'est pas une réinitialisation : cela n'ajoute que ce qui manque et ne modifie jamais une ligne que vous avez éditée. yarn db:reset supprime toutes les tables, sur SQLite comme sur MySQL, avant yarn seed.

Repartir des données d'exemple

Sans API, vos modifications sont conservées dans le navigateur. Pour retrouver les données d'exemple, exécutez ceci dans la console du navigateur, sur la page du tableau de bord :

Console du navigateur
localStorage.removeItem("mock_db_v1"); location.reload();

Bloqué sur une étape ?

Trouvez une solution avant de tout recommencer.

Dépannage

Préférences des Cookies

Nous utilisons des cookies pour améliorer votre expérience de navigation, analyser le trafic du site et personnaliser le contenu. En cliquant sur "Accepter Tout", vous consentez à notre utilisation des cookies pour l'analyse et la publicité personnalisée.