Ir al artículo
Aniq-UI

Food StudioVariables de entorno

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

ArchivoLo leeContiene secretos
back-end/.envLa API, con yarn dev y dentro de Docker ComposeSí. Nunca lo incluyas en un commit.
storefront/.envEl sitio web de pedidos, durante la construcciónNo. Todos los valores son públicos.
admin-dashboard/.envEl panel del personal, durante la construcciónNo. Todos los valores son públicos.
.env junto a docker-compose.ymlDocker Compose, para el paquete Full StackNo

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.

VariableQué hace
NODE_ENVdevelopment en local, que crea y actualiza las tablas al iniciarse. production en un servidor en producción, que nunca toca las tablas.
PORTEl puerto de la API, 8000. Ambos frontends apuntan a él.
DB_TYPEsqlite (como en .env.example) o mysql.
SQLITE_DATABASERuta del archivo SQLite, ./database.sqlite por defecto.
JWT_SECRETFirma cada inicio de sesión. Obligatorio. El valor del ejemplo solo se acepta fuera de producción.
JWT_EXPIRATIONCuánto dura un inicio de sesión, 7d por defecto.
CORS_ORIGINLas 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_URLLa dirección del panel, desde la que se conectan sus notificaciones en directo. Obligatorio en producción para esas notificaciones.
STOREFRONT_URLLa 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_URLLa dirección pública de esta API, adonde Stripe y PayPal devuelven primero el navegador. Por defecto, http://localhost en PORT.
TRUST_PROXYOpcional. El número de proxies inversos delante de la API, para que los límites por dirección cuenten al visitante real.
RATE_LIMIT_LOGINOpcional. 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_RESETOpcional. 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:

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

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-name

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

VariableAplicaciónQué hace
NEXT_PUBLIC_API_BASE_URLAmbosLa dirección de la API incluido /api, http://localhost:8000/api por defecto.
NEXT_PUBLIC_MEDIA_HOSTNAMEAmbosEl 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_URLPanelLa dirección de la API sin /api, para los pedidos y las notificaciones en directo.
NEXT_PUBLIC_DASHBOARD_URLPanelLa propia dirección del panel, para los enlaces absolutos y la aplicación instalable.
NEXT_PUBLIC_STOREFRONT_URLPanelAdónde lleva el enlace "View storefront" de la barra de navegación.
NEXT_PUBLIC_MAP_STYLE_LIGHT, NEXT_PUBLIC_MAP_STYLE_DARKSitio web (solo tema claro), panelEstilos de teselas de mapa opcionales. Vacío usa los estilos públicos de OpenFreeMap, que no necesitan clave.
API_INTERNAL_URLSitio webOpcional, 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_STANDALONEAmbostrue 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.

VariablePor defectoQué hace
SITE_PORT3030El puerto del sitio web en tu equipo.
ADMIN_PORT3031El puerto del panel en tu equipo.
API_PORT8000El puerto de la API en tu equipo.
SITE_URL, ADMIN_URL, API_URLLas direcciones locales en esos puertosDónde llega el navegador a cada aplicación. Configura las tres cuando sirvas el conjunto en tus propios dominios.
MEDIA_HOSTNAMEVacíoEl host público de tu bucket, junto con las variables R2_* en back-end/.env.
SEED_DEMO_DATAtruefalse 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_IDVacíoLas etiquetas de marketing del sitio web, todas opcionales.
NEXT_PUBLIC_ANALYTICS_CURRENCYUSDLa 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.

El .env de la API
PUBLIC_MEDIA_URL=http://localhost:8000/media
MEDIA_UPLOAD_DIR=./public/media/uploads

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

El .env de la API
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.dev

Pagos

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.

El .env de la API
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret

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

El .env de la API
RESEND_API_KEY=re_your-sending-access-key
MAIL_FROM=Food Studio <noreply@your-domain.com>
MAIL_MAX_PER_ADDRESS_PER_DAY=5

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

  1. En el .env de la API, configura NODE_ENV=production y un JWT_SECRET largo y aleatorio propio.
  2. Configura CORS_ORIGIN con las direcciones del sitio web y del panel, FRONTEND_URL con la del panel, STOREFRONT_URL con la del sitio web, API_PUBLIC_URL con la de la API, y PUBLIC_MEDIA_URL con la dirección de la API seguida de /media.
  3. En una base de datos nueva, ejecuta yarn build, luego yarn seed:prod una vez (o yarn db:sync:prod para tablas vacías), y luego yarn start:prod. No hay migraciones: el seeder es la herramienta del esquema.
  4. Guarda los archivos subidos en un almacenamiento persistente: un bucket, o MEDIA_UPLOAD_DIR en un disco que sobreviva a un despliegue.
  5. Apunta la comprobación de estado de tu proveedor de hosting a /api/health, y configura TRUST_PROXY cuando haya un proxy inverso delante de la API.
  6. Construye cada frontend con NEXT_PUBLIC_API_BASE_URL apuntando a tu API desplegada; el panel, además, con NEXT_PUBLIC_WEBSOCKET_BASE_URL, NEXT_PUBLIC_DASHBOARD_URL y NEXT_PUBLIC_STOREFRONT_URL.
  7. En el sitio web, configura domain.url en src/config/brand.config.ts, y reescribe la política de privacidad y los términos en messages/legal para tu negocio.
  8. 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.
  9. 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.

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