Variables de entorno
Qué hace cada ajuste de los archivos .env de la API y de los frontends, y cuáles necesitas.
Para el paquete Full Stack
Dónde están los ajustes
| Archivo | Lo lee | Contiene secretos |
|---|---|---|
back-end/.env | La API, con yarn dev y dentro de Docker Compose | Sí. Nunca lo incluyas en un commit. |
storefront/.env | El sitio web de pedidos, durante la construcción | No. Todos los valores son públicos. |
admin-dashboard/.env | El panel del personal, durante la construcción | No. Todos los valores son públicos. |
.env junto a docker-compose.yml | Docker Compose, para el paquete Full Stack | No |
Crea el archivo de cada aplicación a partir del .env.example que tiene al lado, que documenta cada variable: cp .env.example .env. Los ejemplos funcionan tal cual para una ejecución local.
Dónde están los ajustes
Un archivo, .env en la carpeta del sitio web, que se lee cuando se construye el sitio web. Todos sus valores son públicos, así que nunca contiene un secreto: las claves de pago y de IA están en el .env de la API. Créalo a partir de .env.example, que apunta a una API en http://localhost:8000: cp .env.example .env.
Dónde están los ajustes
Un archivo, .env en la carpeta del panel, que se lee cuando se construye el panel. Todos sus valores son públicos, así que nunca contiene un secreto: las claves de IA están en el .env de la API. Créalo a partir de .env.example, que apunta a una API en http://localhost:8000: cp .env.example .env.
Dónde están los ajustes
Un archivo, .env en la carpeta de la API, que la API lee con yarn dev, y un contenedor cuando se lo pasas con --env-file .env. Contiene secretos: nunca lo subas a un commit. Créalo a partir de .env.example, que documenta cada variable y funciona tal cual para una ejecución local: cp .env.example .env.
La imagen de Docker define sus propios valores por defecto, así que docker run funciona sin archivo: SQLite en /data/database.sqlite, archivos subidos en /data/uploads, CORS_ORIGIN para los dos frontends locales, PUBLIC_MEDIA_URL=http://localhost:8000/media y SEED_DEMO_DATA=false. Cambia cualquiera de ellos con -e.
Lo esencial de la API
La API comprueba JWT_SECRET y, en producción, CORS_ORIGIN antes de iniciarse. Si falta alguno o no se puede usar, se detiene con una línea que dice qué corregir.
| Variable | Qué hace |
|---|---|
NODE_ENV | development en local, que crea y actualiza las tablas al iniciarse. production en un servidor en producción, que nunca toca las tablas. |
PORT | El puerto de la API, 8000. Ambos frontends apuntan a él. |
DB_TYPE | sqlite (como en .env.example) o mysql. |
SQLITE_DATABASE | Ruta del archivo SQLite, ./database.sqlite por defecto. |
JWT_SECRET | Firma cada inicio de sesión. Obligatorio. El valor del ejemplo solo se acepta fuera de producción. |
JWT_EXPIRATION | Cuánto dura un inicio de sesión, 7d por defecto. |
CORS_ORIGIN | Las direcciones del sitio web y del panel, separadas por comas. La dirección de retorno de un pago alojado debe estar en una de ellas. Si no se configura, solo se permiten http://localhost:3030 y http://localhost:3031; obligatorio en producción. |
FRONTEND_URL | La dirección del panel, desde la que se conectan sus notificaciones en directo. Obligatorio en producción para esas notificaciones. |
STOREFRONT_URL | La dirección del sitio web, adonde un pago y un enlace para restablecer la contraseña envían al cliente. Por defecto, la primera entrada de CORS_ORIGIN. |
API_PUBLIC_URL | La dirección pública de esta API, adonde Stripe y PayPal devuelven primero el navegador. Por defecto, http://localhost en PORT. |
TRUST_PROXY | Opcional. El número de proxies inversos delante de la API, para que los límites por dirección cuenten al visitante real. |
RATE_LIMIT_LOGIN | Opcional. Los inicios de sesión fallidos que puede hacer una dirección en un formulario de inicio de sesión en 15 minutos antes de 429, 10 por defecto. |
RATE_LIMIT_ORDERS, RATE_LIMIT_PAYMENT_SESSION, RATE_LIMIT_TRACKING, RATE_LIMIT_REGISTER, RATE_LIMIT_CONTACT, RATE_LIMIT_PASSWORD_RESET | Opcional. Los límites por dirección de los formularios públicos; .env.example indica el valor por defecto de cada uno y su intervalo. |
Genera tu propio JWT_SECRET con:
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"Cada función opcional de abajo está desactivada mientras sus líneas en .env.example sigan comentadas.
Usa MySQL en lugar de SQLite
Crea una base de datos vacía y luego configura el controlador y la conexión en el .env de la API:
DB_TYPE=mysql
DB_HOST=your-mysql-host
DB_PORT=3306
DB_USERNAME=your-mysql-username
DB_PASSWORD=your-mysql-password
DB_DATABASE=your-database-nameLuego ejecuta yarn seed para el restaurante de demostración, o yarn db:sync para las tablas sin datos. La API en ejecución solo crea y actualiza las tablas por sí misma cuando NODE_ENV=development, así que con NODE_ENV=production uno de esos comandos se ejecuta antes del primer inicio (yarn seed:prod o yarn db:sync:prod después de yarn build).
Sitio web de pedidos y panel del personal
Cada valor NEXT_PUBLIC_* se compila en el JavaScript que carga el navegador, y cualquiera que abra la página puede leerlo. Nunca pongas un secreto en estos archivos, y reconstruye después de cambiar uno.
| Variable | Aplicación | Qué hace |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL | Ambos | La dirección de la API incluido /api, http://localhost:8000/api por defecto. |
NEXT_PUBLIC_MEDIA_HOSTNAME | Ambos | El host https de tu bucket de imágenes, por ejemplo pub-1234.r2.dev, o el de la API cuando sirve las imágenes en un dominio público. Next.js redimensiona las imágenes de ese host; cualquier otra imagen se muestra tal cual. Solo el host. Déjalo vacío mientras la API funcione en localhost. |
NEXT_PUBLIC_WEBSOCKET_BASE_URL | Panel | La dirección de la API sin /api, para los pedidos y las notificaciones en directo. |
NEXT_PUBLIC_DASHBOARD_URL | Panel | La propia dirección del panel, para los enlaces absolutos y la aplicación instalable. |
NEXT_PUBLIC_STOREFRONT_URL | Panel | Adónde lleva el enlace "View storefront" de la barra de navegación. |
NEXT_PUBLIC_MAP_STYLE_LIGHT, NEXT_PUBLIC_MAP_STYLE_DARK | Sitio web (solo tema claro), panel | Estilos de teselas de mapa opcionales. Vacío usa los estilos públicos de OpenFreeMap, que no necesitan clave. |
API_INTERNAL_URL | Sitio web | Opcional, solo en el servidor, se lee cuando se inicia el contenedor. Dónde llega a la API el propio servidor del sitio web cuando la dirección del navegador no funciona desde dentro de él, como en Docker Compose (http://api:8000/api). En otros casos, déjalo sin configurar. |
BUILD_STANDALONE | Ambos | true hace que yarn build genere un servidor autónomo, lo que configuran los Dockerfiles. En los demás casos, déjalo sin configurar. |
Las etiquetas de marketing del sitio web también son valores NEXT_PUBLIC_*.
Opciones de Docker Compose
No hay que configurar nada para una ejecución local. Para cambiar algo, ponlo en un archivo .env junto a docker-compose.yml y vuelve a ejecutar docker compose up --build: los frontends incorporan estos valores al construirse.
| Variable | Por defecto | Qué hace |
|---|---|---|
SITE_PORT | 3030 | El puerto del sitio web en tu equipo. |
ADMIN_PORT | 3031 | El puerto del panel en tu equipo. |
API_PORT | 8000 | El puerto de la API en tu equipo. |
SITE_URL, ADMIN_URL, API_URL | Las direcciones locales en esos puertos | Dónde llega el navegador a cada aplicación. Configura las tres cuando sirvas el conjunto en tus propios dominios. |
MEDIA_HOSTNAME | Vacío | El host público de tu bucket, junto con las variables R2_* en back-end/.env. |
SEED_DEMO_DATA | true | false empieza con tablas vacías y sin cuentas en lugar del restaurante de demostración. Solo importa en un volumen nuevo. |
NEXT_PUBLIC_GTM_ID, NEXT_PUBLIC_GA4_MEASUREMENT_ID, NEXT_PUBLIC_META_PIXEL_ID, NEXT_PUBLIC_TIKTOK_PIXEL_ID, NEXT_PUBLIC_SNAPCHAT_PIXEL_ID, NEXT_PUBLIC_PINTEREST_TAG_ID | Vacío | Las etiquetas de marketing del sitio web, todas opcionales. |
NEXT_PUBLIC_ANALYTICS_CURRENCY | USD | La moneda que se envía con cada valor registrado. |
Cambia un puerto cuando otro programa ya lo usa, por ejemplo ADMIN_PORT=3041. CORS_ORIGIN, FRONTEND_URL, STOREFRONT_URL, API_PUBLIC_URL y PUBLIC_MEDIA_URL de la API, y la dirección de la API de los frontends, se construyen a partir de los puertos y de las tres direcciones, así que se ajustan solos.
El contenedor de la API también lee back-end/.env cuando existe, así que las claves de pagos, correo, medios e IA se configuran en un solo lugar tanto para yarn dev como para Docker. El archivo compose prevalece para los valores que cambian dentro de un contenedor: la ruta de la base de datos, la carpeta de archivos subidos, el puerto, NODE_ENV=production y las direcciones de arriba. La base de datos y los archivos subidos viven en el volumen food-studio-data.
Almacenamiento multimedia
La API sirve ella misma las imágenes de los datos de demostración, desde public/media/food-studio, en /media/food-studio/…. Los archivos subidos desde el panel (fotos de platos, fotos de perfil, los resultados del estudio de IA) se guardan en el disco de la API bajo MEDIA_UPLOAD_DIR y se sirven en /media/uploads/…, salvo que haya un bucket configurado.
PUBLIC_MEDIA_URL=http://localhost:8000/media
MEDIA_UPLOAD_DIR=./public/media/uploadsPUBLIC_MEDIA_URL es la dirección desde la que un navegador llega a /media. La carga de datos la escribe en la dirección de cada imagen, así que configúrala antes de la primera carga de datos en un servidor. En un servidor, apunta MEDIA_UPLOAD_DIR a un almacenamiento persistente; con Docker está en el volumen de datos.
Para enviar los archivos subidos a Cloudflare R2, o a cualquier bucket compatible con S3, configura las cinco variables y da a los dos frontends el host público del bucket mediante NEXT_PUBLIC_MEDIA_HOSTNAME (con Docker Compose, MEDIA_HOSTNAME). Configura las cinco o ninguna.
R2_ACCESS_KEY_ID=your-r2-access-key-id
R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
R2_BUCKET_NAME=your-bucket-name
R2_PUBLIC_URL=https://your-public-url.r2.devPagos
El pago envía al cliente a la propia página de Stripe o de PayPal. Configura STRIPE_SECRET_KEY y STRIPE_WEBHOOK_SECRET, o PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET y PAYPAL_WEBHOOK_ID (con PAYPAL_ENV, sandbox por defecto). Sin ningún proveedor configurado, el pago ofrece un pago de demostración integrado que marca un pedido como pagado sin mover dinero.
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secretCorreo electrónico
Los enlaces para restablecer la contraseña se envían mediante Resend. Hacen falta los dos valores: una clave con acceso de envío y una dirección de remitente en un dominio verificado en Resend. Sin ellos, "Forgot password" sigue respondiendo como siempre, no se envía ningún mensaje y el registro indica que el correo no está configurado.
RESEND_API_KEY=re_your-sending-access-key
MAIL_FROM=Food Studio <noreply@your-domain.com>
MAIL_MAX_PER_ADDRESS_PER_DAY=5El enlace abre la página de restablecimiento del sitio web en STOREFRONT_URL, en el idioma del cliente, y funciona una vez durante una hora. Una dirección recibe como máximo MAIL_MAX_PER_ADDRESS_PER_DAY mensajes al día, 5 por defecto.
Funciones de IA
Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.
Activar las funciones de IA: las claves de los proveedores, los modelos que usa cada función y el modelo para quitar el fondo.
El servidor MCP
Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.
Permitir que los agentes de programación y otros clientes MCP usen las herramientas del asistente: la clave y el endpoint.
Modo demostración
Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.
Ejecutar una demo pública: los interruptores de demo, las cuentas por visitante y lo que pueden cambiar los visitantes.
Pasar a producción
Antes de desplegar en cualquier sitio público:
- En el
.envde la API, configuraNODE_ENV=productiony unJWT_SECRETlargo y aleatorio propio. - Configura
CORS_ORIGINcon las direcciones del sitio web y del panel,FRONTEND_URLcon la del panel,STOREFRONT_URLcon la del sitio web,API_PUBLIC_URLcon la de la API, yPUBLIC_MEDIA_URLcon la dirección de la API seguida de/media. - En una base de datos nueva, ejecuta
yarn build, luegoyarn seed:produna vez (oyarn db:sync:prodpara tablas vacías), y luegoyarn start:prod. No hay migraciones: el seeder es la herramienta del esquema. - Guarda los archivos subidos en un almacenamiento persistente: un bucket, o
MEDIA_UPLOAD_DIRen un disco que sobreviva a un despliegue. - Apunta la comprobación de estado de tu proveedor de hosting a
/api/health, y configuraTRUST_PROXYcuando haya un proxy inverso delante de la API. - Construye cada frontend con
NEXT_PUBLIC_API_BASE_URLapuntando a tu API desplegada; el panel, además, conNEXT_PUBLIC_WEBSOCKET_BASE_URL,NEXT_PUBLIC_DASHBOARD_URLyNEXT_PUBLIC_STOREFRONT_URL. - En el sitio web, configura
domain.urlensrc/config/brand.config.ts, y reescribe la política de privacidad y los términos enmessages/legalpara tu negocio. - En el panel, configura tus cocinas, sus horarios y los códigos postales de entrega, tus tarifas y códigos promocionales, y cambia el reloj de servicio a Real: la carga de datos lo deja en el reloj de demostración, que mantiene todas las cocinas abiertas.
- Cambia las contraseñas de los datos de demostración, o elimina las cuentas, y cambia los pagos a claves reales.
No para un restaurante con pedidos reales
yarn railway:setup construye, descarga el modelo para quitar el fondo, elimina todas las tablas y carga los datos, cada vez que se ejecuta, y yarn drop:prod elimina todas las tablas. Sirven para un entorno nuevo, nunca para el comando de construcción de un restaurante en producción.