Ir al artículo
Aniq-UI

Food StudioSolución de problemas

Solución de problemas

Los errores que puedes encontrar al instalar el restaurante, qué causa cada uno y cómo solucionarlo.

Para el paquete Full Stack

Docker no se está ejecutando

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

Las versiones antiguas de Docker muestran "Cannot connect to the Docker daemon" en su lugar. En ambos casos, el motor de Docker no está iniciado.

  1. Abre Docker Desktop

    Inicia Docker Desktop y espera a que indique que el motor está en ejecución. En Linux, inicia el servicio: sudo systemctl start docker.

  2. Comprueba que Docker responde

    Terminal
    docker info

    Resultado esperado: Muestra una sección Server en lugar de un error.

  3. Vuelve a ejecutar tu comando de inicio

    docker compose up --build para el paquete Full Stack, o tus comandos docker build y docker run para una sola aplicación.

Un puerto ya está en uso

Lo que ves
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 :::3031

Las dos primeras líneas vienen de Docker y la última de yarn dev. Otro programa ya escucha en el 3030, el 3031 o el 8000: a menudo una ejecución anterior del restaurante o el servidor de desarrollo de otro proyecto.

  1. Averigua qué ocupa el puerto

    En macOS o Linux, con el puerto del mensaje:

    Terminal
    lsof -i :3031

    En Windows, en PowerShell:

    Terminal
    netstat -ano | findstr :3031
  2. Detenlo

    Cierra ese programa o detén la ejecución anterior: Ctrl+C en su terminal, docker compose down en su carpeta, o docker stop para un contenedor que iniciaste con docker run. Luego vuelve a iniciar el restaurante.

  3. O ejecuta el restaurante en otros puertos

    Con el paquete completo en Docker, crea un archivo llamado .env en la carpeta food-studio-full-stack, junto a docker-compose.yml, con el puerto que necesites. SITE_PORT mueve el sitio web, ADMIN_PORT el panel y API_PORT la API; las direcciones que usan las aplicaciones, incluida CORS_ORIGIN, se ajustan solas.

    food-studio-full-stack/.env
    ADMIN_PORT=3041

    Luego ejecuta de nuevo el mismo comando. Un inicio fallido continúa donde se detuvo:

    Terminalen food-studio-full-stack
    docker compose up --build

    Resultado esperado: La aplicación responde en su nuevo puerto, aquí localhost:3041Local.

Para una sola aplicación iniciada con docker run, cambia el número a la izquierda de -p, por ejemplo -p 3041:3031, y añade la nueva dirección a CORS_ORIGIN de la API. Sin Docker, los puertos están fijados en los archivos .env: para mover la API, cambia a la vez PORT en el .env de la API y NEXT_PUBLIC_API_BASE_URL en los dos frontends; para mover un frontend, añade su nueva dirección a CORS_ORIGIN.

Configuración

La construcción de Docker falla

La primera construcción descarga las imágenes base y todas las dependencias, y luego construye las imágenes. Si algo lo impide, se detiene con "failed to solve" y el paso que falló.

  • Sin conexión o tiempo de espera agotado: la construcción necesita acceso a internet. Vuelve a ejecutar el comando cuando tengas conexión; los pasos terminados quedan en caché.
  • No space left on device: libera espacio en Docker Desktop o revisa cuánto usa Docker con docker system df.
  • Falla siempre en el mismo paso: vuelve a construir sin la caché y luego inicia.
Terminalen food-studio-full-stack
docker compose build --no-cache
docker compose up

En un paquete de una sola aplicación, añade --no-cache a tu comando docker build.

Un primer inicio que parece atascado normalmente sigue cargando el restaurante de demostración. El sitio web y el panel solo arrancan cuando la API indica que está en buen estado.

Yarn dice que su versión es 1.22

Lo que ves
This project's package.json defines "packageManager": "yarn@4…". However the current global version of Yarn is 1.22…

Cada aplicación fija Yarn 4 a través de Corepack. Este mensaje significa que Corepack aún no está habilitado, así que respondió en su lugar el Yarn global antiguo.

Terminal
corepack enable

Después vuelve a ejecutar yarn install. Si tu Node.js no trae Corepack, instálalo antes con npm install -g corepack.

Una instalación o un inicio falla con una versión antigua de Node.js

Cada aplicación declara Node.js 24 o más reciente, y su imagen de Docker funciona con Node.js 24. Yarn no detiene por sí mismo una versión antigua, así que una versión antigua de Node.js aparece más tarde, como una instalación que no consigue construir un paquete o una aplicación que se detiene al iniciar.

Terminal
node -v

Si muestra una versión inferior a 24, instala Node.js 24 o más reciente, vuelve a ejecutar corepack enable, luego elimina la carpeta node_modules de la aplicación y vuelve a ejecutar yarn install. Con Docker nada de esto aplica: las imágenes traen su propio Node.js.

El sitio web responde 500 en desarrollo

La primera vez que yarn dev abre una página, Next.js descarga las fuentes de Google del sitio. Sin conexión a internet, o con fonts.googleapis.com bloqueado, cada página responde 500 y la consola del navegador nombra un archivo de fuente, como ibm_plex_sans_arabic.

Conéctate y vuelve a cargar la página. yarn build y la compilación de Docker descargan las fuentes una sola vez, al compilar, así que un sitio compilado ya no las necesita.

La API se detiene antes de iniciarse

Lo que ves
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, …

La API revisa sus ajustes antes de iniciarse y muestra una línea por cada problema. Las causas:

  • No hay archivo `.env`, o `JWT_SECRET` está vacío. Crea el archivo en la carpeta de la API con cp .env.example .env.
  • `JWT_SECRET` sigue siendo el valor de ejemplo con `NODE_ENV=production`. Cualquiera podría firmar un token con el ejemplo público, así que un inicio en producción lo rechaza. Genera tu propio secreto.
  • `CORS_ORIGIN` está vacío con `NODE_ENV=production`. Escribe las direcciones del sitio web y del panel, separadas por comas.

Genera un secreto con:

Terminal
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"

Con Docker no necesitas uno: un contenedor sin un JWT_SECRET propio, o con el de ejemplo, genera un secreto y lo guarda en el volumen de datos.

El menú está vacío y nadie puede iniciar sesión

Lo que ves
→ No database at /data/database.sqlite. Creating the tables, no data (set SEED_DEMO_DATA=true for the demo).

La base de datos se creó solo con las tablas. Eso ocurre cuando el contenedor de la API se inicia en un volumen nuevo sin SEED_DEMO_DATA=true, cuando el paquete completo se ejecuta con SEED_DEMO_DATA=false en el .env junto a docker-compose.yml, o sin Docker cuando se ejecutó yarn db:sync en lugar de yarn seed. No hay menú, ni cocina, ni ninguna cuenta con la que iniciar sesión.

  • Sin Docker: ejecuta yarn seed en la carpeta de la API. Añade el restaurante de demostración y sus cuentas a las tablas que tienes.
  • Paquete completo en Docker: quita SEED_DEMO_DATA=false del .env, luego ejecuta docker compose down -v y docker compose up. El volumen de datos se vuelve a crear con el restaurante de demostración.
  • Contenedor de la API: elimina el contenedor, borra su volumen y vuelve a ejecutarlo con -e SEED_DEMO_DATA=true, como en Empieza de cero con datos de demostración nuevos, más abajo.

El contenedor nunca vuelve a cargar datos en una base de datos existente, diga lo que diga SEED_DEMO_DATA, así que la variable solo importa en un volumen nuevo.

El inicio de sesión falla

  • Comprueba la cuenta y la aplicación. El personal inicia sesión en el panel, en el puerto 3031: owner@foodstudio.example con FoodDemo2026!. Los clientes inician sesión en el sitio web, en el puerto 3030: sam@foodstudio.example con FoodDemo2026!. Una cuenta de cliente no puede abrir el panel, y una cuenta del personal no puede iniciar sesión en el sitio web.
  • El panel dice "We could not sign you in. Check your email and password, then try again." cuando la contraseña es incorrecta, el correo es desconocido o la base de datos no tiene cuentas. Después de demasiados intentos fallidos, en su lugar te pide que esperes unos minutos. Revisa los puntos de abajo uno a uno.
  • La base de datos no tiene cuentas cuando se creó con SEED_DEMO_DATA=false. Consulta El menú está vacío y nadie puede iniciar sesión, más arriba.
  • Diez inicios de sesión fallidos desde una misma dirección en 15 minutos bloquean ese formulario de inicio de sesión para esa dirección. La API responde 429 hasta que el fallo más antiguo tenga 15 minutos. Espera, o reinicia la API: el recuento se guarda en su memoria.
  • Cambiaste la contraseña del propietario y ya no la tienes: empieza de cero con datos de demostración nuevos, más abajo.

El inicio de sesión falla

  • Comprueba la cuenta y la ruta. El personal inicia sesión en POST /api/auth/login (el propietario es owner@foodstudio.example con FoodDemo2026!); los clientes en POST /api/auth/customer/login (sam@foodstudio.example con FoodDemo2026!). Un inicio de sesión fallido responde 401 con el mismo mensaje tanto si el correo como si la contraseña son incorrectos.
  • No funciona ninguna cuenta: la base de datos se creó sin el restaurante de demostración. Ejecuta yarn seed, o inicia el contenedor con -e SEED_DEMO_DATA=true en un volumen nuevo.
  • Una respuesta `429` significa que una dirección falló 10 inicios de sesión en esa ruta en 15 minutos. Se levanta cuando el fallo más antiguo tiene 15 minutos, o cuando la API se reinicia. RATE_LIMIT_LOGIN cambia el número.

El inicio de sesión falla

Tu aplicación inicia sesión contra la API de la plantilla, así que la cuenta tiene que existir allí. En una API con los datos de demostración, el personal inicia sesión en el panel con owner@foodstudio.example y los clientes en el sitio web con sam@foodstudio.example, ambos con FoodDemo2026!. Si no funciona ninguna cuenta, o la API se inició sin sus datos de demostración (ejecuta yarn seed en su carpeta, o inicia su contenedor en un volumen nuevo con -e SEED_DEMO_DATA=true), o la aplicación no llega a la API: consulta el problema siguiente.

Las páginas se quedan vacías y el navegador informa de CORS

Lo que ves
Access to fetch at 'http://localhost:8000/api/…' from origin 'http://localhost:3041' has been blocked by CORS policy

La consola del navegador muestra esta línea cuando un frontend funciona en una dirección que la API no acepta. La API solo responde a los navegadores desde las direcciones de CORS_ORIGIN, que por defecto son http://localhost:3030 y http://localhost:3031. Un sitio web o un panel movido a otro puerto, o servido en tu propio dominio, se rechaza hasta que se añade a la lista.

El .env de la API
CORS_ORIGIN=http://localhost:3030,http://localhost:3041
FRONTEND_URL=http://localhost:3041
  • Escribe cada dirección exactamente como la muestra el navegador, con el esquema y el puerto y sin barra final, separadas por comas. Luego reinicia la API.
  • FRONTEND_URL es la dirección del panel, desde la que se conectan sus notificaciones en directo, y STOREFRONT_URL la del sitio web, adonde un pago y un enlace para restablecer la contraseña envían al cliente. Muévelas junto con la aplicación.
  • Para un contenedor de la API, pasa los mismos valores con -e, por ejemplo -e CORS_ORIGIN=http://localhost:3030,http://localhost:3041.
  • Con el paquete completo en Docker no editas estos valores: los configuran SITE_PORT, ADMIN_PORT, SITE_URL y ADMIN_URL en el .env junto a docker-compose.yml.
  • Un frontend que no llega a la API en absoluto, porque está detenida o en otra dirección, falla de la misma forma pero sin la línea de CORS. Comprueba que localhost:8000/api/healthLocal responde y que NEXT_PUBLIC_API_BASE_URL del frontend apunta a esa API.

Las imágenes de los platos no cargan

La API sirve las imágenes de los datos de demostración en /media/food-studio/…, y la carga de datos escribe la dirección completa de cada imagen a partir de PUBLIC_MEDIA_URL, que por defecto es http://localhost:8000/media. Una imagen se rompe cuando esa dirección no llega a la API desde el navegador.

  • La API funciona en otro puerto o dominio. Configura PUBLIC_MEDIA_URL con la dirección pública de la API seguida de /media, por ejemplo -e PUBLIC_MEDIA_URL=http://localhost:8010/media con docker run -p 8010:8000. Con el paquete completo en Docker, API_PORT y API_URL lo configuran por ti.
  • La API cambió de dirección después del primer inicio. Reinicia la API con PUBLIC_MEDIA_URL configurado con la nueva dirección (con Docker Compose, lo hace API_PORT o API_URL). Al iniciarse, apunta a esa dirección cada imagen guardada bajo /media/food-studio/ y /media/uploads/, y su registro indica cuántas cambió.
  • Los archivos subidos a un bucket no cargan. R2_PUBLIC_URL debe ser la dirección pública del bucket, y el bucket debe permitir lecturas públicas.
  • Las imágenes cargan, pero despacio y a tamaño completo. Los frontends solo redimensionan las imágenes del host https de NEXT_PUBLIC_MEDIA_HOSTNAME (con Docker Compose, MEDIA_HOSTNAME), escrito solo como host, por ejemplo pub-1234.r2.dev. Cualquier otra imagen se muestra tal cual. Vuelve a construir el frontend después de cambiarlo.

Un cambio en el .env de un frontend no tiene efecto

Cada valor NEXT_PUBLIC_* se compila en el JavaScript que carga el navegador cuando se construye la aplicación. Cambiar el archivo no cambia nada hasta que la aplicación se vuelve a construir.

Cómo lo ejecutasDespués de cambiar un valor
yarn devDetenlo y vuelve a ejecutar yarn dev.
yarn build y yarn startVuelve a ejecutar yarn build y luego yarn start.
Docker ComposeEjecuta docker compose up --build. Configura el valor en el .env junto a docker-compose.yml, no en la carpeta de la aplicación.
docker build para una aplicaciónVuelve a construir la imagen con el valor como --build-arg.

Los pedidos nuevos no aparecen solos en el panel

La campana del panel y sus actualizaciones de pedidos en directo usan un WebSocket hacia la API. El panel se conecta a NEXT_PUBLIC_WEBSOCKET_BASE_URL, la dirección de la API sin /api, y la API solo acepta la conexión desde FRONTEND_URL, la propia dirección del panel.

  • Configura ambos según dónde funcionan realmente las aplicaciones, luego reinicia la API y vuelve a construir el panel.
  • Si FRONTEND_URL no está configurado, solo se acepta http://localhost:3031, así que en cualquier otra dirección se rechaza la conexión en directo.
  • Al recargar siempre se ven los últimos pedidos: solo las actualizaciones en directo dependen de la conexión.

Una función indica que no está conectada

Los pagos con tarjeta y PayPal, la subida de archivos a un bucket, el correo para restablecer la contraseña, el asistente de IA y el estudio de IA solo se activan cuando sus variables están configuradas en el .env de la API. En .env.example están comentadas, así que un archivo copiado empieza limpio y cada una de esas funciones queda desactivada.

  • Quita el # delante de la línea y pega tu valor real sobre el del ejemplo.
  • Reinicia la API después de cambiar su .env. Con Docker Compose la API también lee back-end/.env, así que basta con volver a ejecutar docker compose up; un contenedor de la API por sí solo necesita --env-file .env en su docker run.
  • El correo para restablecer la contraseña necesita RESEND_API_KEY y MAIL_FROM. Sin ellos, "Forgot password" sigue respondiendo como siempre, y el registro dice "Mail is not configured: set RESEND_API_KEY and MAIL_FROM to send password reset messages."

Un pedido pagado sigue sin pagar

Un pedido cuenta como pagado solo cuando la API ha confirmado el pago con Stripe o PayPal, al volver el cliente o al llegar el webhook del proveedor. Si un pedido sigue sin pagar después de que el cliente pagó:

  • El cliente nunca volvió a la API. El proveedor envía el navegador a API_PUBLIC_URL, que por defecto es http://localhost:8000. En tu propio dominio, configúralo con la dirección pública de la API.
  • El webhook no está configurado. Apúntalo a la dirección de tu API seguida de /api/payments/webhooks/stripe o /api/payments/webhooks/paypal, y configura STRIPE_WEBHOOK_SECRET o PAYPAL_WEBHOOK_ID. Una llamada sin firmar o alterada se rechaza con 401.
  • El cliente abandonó la página de pago. Un pedido al que nadie volvió se comprueba con el proveedor, a los 35 minutos con Stripe y a las 3 horas con PayPal, y se cancela si no se pagó, lo que devuelve su stock y sus puntos.

El pago indica que la cocina está cerrada o que la dirección está fuera de la zona

Lo que ves
This kitchen is closed. Choose another kitchen.
Delivery is unavailable here. Try pickup.
  • Cerrada. Una cocina solo acepta pedidos durante su horario, en su propia zona horaria. Con el reloj de servicio en Real, fuera de ese horario el pago rechaza tanto la entrega como la recogida. Cambia el horario en Settings, Restaurant, o prueba con otra cocina.
  • Fuera de la zona. La entrega solo llega a los códigos postales que indica cada cocina. Las cocinas de demostración entregan en códigos postales como 10001 y 10002. Añade tus propios códigos postales a cada cocina en Settings, Restaurant.
  • Por debajo del mínimo. Un pedido a domicilio necesita al menos el mínimo de entrega en comida, $10.00 en los ajustes de demostración.

Todos los visitantes reciben "Too many attempts" detrás de un proxy

Los formularios públicos tienen límites por dirección de visitante: pedidos, sesiones de pago, seguimiento, registro, el formulario de contacto, el restablecimiento de contraseñas y los inicios de sesión fallidos. Detrás de un proxy inverso, todos los visitantes pueden parecer la única dirección del proxy y compartir un mismo cupo. Indica a la API cuántos proxies tiene delante:

El .env de la API
TRUST_PROXY=1

Las variables RATE_LIMIT_* de .env.example cambian cada límite. Los recuentos viven en la memoria de la API, así que un reinicio los borra.

MySQL no arranca o no carga los datos

La API crea sus tablas en una base de datos que ya existe; no crea la base de datos en sí. Crea primero una base de datos vacía, pon su nombre en DB_DATABASE en el .env de la API y luego ejecuta yarn seed (o yarn db:sync para las tablas sin datos de demostración).

  • Revisa los cinco valores de conexión DB_* y que DB_TYPE=mysql.
  • Con NODE_ENV=production la API en ejecución nunca crea tablas, así que uno de esos comandos tiene que ejecutarse antes del primer inicio (yarn seed:prod o yarn db:sync:prod después de yarn build).
  • La imagen de Docker crea la base de datos por sí sola solo con SQLite. Con MySQL, ejecuta tú mismo una vez la carga de datos o el comando del esquema.

El contenedor de la API no encuentra su entrypoint

Lo que ves
exec /usr/local/bin/docker-entrypoint.sh: no such file or directory

El script tiene finales de línea de Windows, que un editor o Git en Windows pueden añadir. El Dockerfile de la API incluido los elimina durante la construcción, así que esto solo aparece con una imagen construida a partir de un Dockerfile modificado. Conserva su línea sed -i 's/\r$//', o guarda el script con finales de línea LF, y vuelve a construir sin la caché.

La carpeta se ve diferente

Ejecuta los comandos dentro de la carpeta en la que se extrae el ZIP. Si no tienes el comando unzip, extráelo con tu gestor de archivos; algunas herramientas añaden una carpeta extra con el nombre del ZIP, así que entra en la carpeta interior.

PaqueteCarpetaContiene
Full Stackfood-studio-full-stackadmin-dashboard, back-end, storefront, docker-compose.yml
Sitio web de pedidosfood-studio-websiteDockerfile, package.json, .env.example
Panel del personalfood-studio-staff-dashboardDockerfile, package.json, .env.example
API Backendfood-studio-backendDockerfile, package.json, .env.example

Empieza de cero con datos de demostración nuevos

Esto elimina tus datos

Se elimina todo lo que creaste en local y se vuelve a cargar el restaurante de demostración.

Con el paquete completo en Docker, desde la carpeta food-studio-full-stack:

Terminalen food-studio-full-stack
docker compose down -v
docker compose up

Con un contenedor de API independiente, elimina primero el contenedor (docker ps -a lo muestra, docker rm -f con su id lo elimina), luego borra el volumen y vuelve a ejecutarlo:

Terminal
docker volume rm foodstudio-data
docker run -p 8000:8000 -v foodstudio-data:/data -e SEED_DEMO_DATA=true foodstudio-api

Sin Docker, detén la API y luego, en su carpeta:

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

En PowerShell:

Terminal
Remove-Item database.sqlite*; yarn seed

Volver a ejecutar yarn seed en una base de datos que conservas no es un reinicio: solo añade lo que falta y nunca cambia un valor que editaste. yarn db:reset elimina todas las tablas, tanto en SQLite como en MySQL; ejecuta yarn seed después.

¿Te atascaste en un paso?

Busca una solución antes de empezar de nuevo.

Solución de problemas

Preferencias de Cookies

Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al hacer clic en "Aceptar Todo", consientes nuestro uso de cookies para análisis y publicidad personalizada.