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: los valores NEXT_PUBLIC_* al construir, y REVALIDATE_SECRET y API_INTERNAL_URL en su servidor | Solo REVALIDATE_SECRET, que nunca llega al navegador |
admin-dashboard/.env | El panel del organizador, al construir | No. Todos los valores son públicos. |
.env junto a docker-compose.yml | Docker Compose, para la pila completa, y el contenedor de la API, que lo lee antes que back-end/.env | REVALIDATE_SECRET en un servidor abierto a internet, y OWNER_PASSWORD cuando lo pongas allí |
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 sirven tal cual para una ejecución local, y el inicio con Docker Compose no necesita ningún archivo.
Dónde están los ajustes
Un solo archivo, .env en la carpeta del sitio web. Los valores NEXT_PUBLIC_* que contiene se leen cuando se construye el sitio web y son públicos, así que nunca guardan un secreto. REVALIDATE_SECRET y API_INTERNAL_URL los lee el propio servidor del sitio web al ejecutarse y nunca llegan al navegador. Créalo a partir de .env.example, que apunta a una API en http://localhost:8000: cp .env.example .env. Con Docker, pasa los valores NEXT_PUBLIC_* como --build-arg y los otros dos con -e.
Dónde están los ajustes
Un solo 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 los proveedores 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. Con Docker, pasa los mismos valores como --build-arg.
Dónde están los ajustes
Un solo archivo, .env en la carpeta de la API, que lee la API con yarn dev y un contenedor cuando añades --env-file .env -e NODE_ENV=production a su docker run. Contiene secretos: nunca lo incluyas en un commit. Créalo a partir de .env.example, que documenta cada variable y sirve 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, subidas en /data/uploads, exportaciones CSV en /data/exports, CORS_ORIGIN para los dos frontends locales, FRONTEND_URL=http://localhost:3031, STOREFRONT_URL=http://localhost:3030, PUBLIC_API_URL=http://localhost:8000, 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 (el valor por defecto si no se define) o mysql. |
SQLITE_DATABASE | Ruta del archivo SQLite, ./database.sqlite en .env.example. |
JWT_SECRET | Firma cada inicio de sesión y los códigos QR de las entradas mientras TICKET_SECRET no esté definido. Obligatorio. El valor del ejemplo solo se acepta fuera de producción. |
JWT_EXPIRATION | Cuánto dura un inicio de sesión, 7d si no se define. |
CORS_ORIGIN | Las direcciones del sitio web y del panel, separadas por comas. Sin definir, solo se permiten http://localhost:3030 y http://localhost:3031, nunca todos los orígenes; obligatorio en producción. |
FRONTEND_URL | La dirección del panel, el único origen que aceptan sus conexiones en vivo (notificaciones y cambios de permisos), http://localhost:3031 si no se define. |
STOREFRONT_URL | La dirección del sitio web: las páginas de pago devuelven allí a los compradores, los correos de entradas enlazan a ella y la API actualiza a través de ella las páginas del sitio web. |
PUBLIC_API_URL | La dirección pública propia de la API, usada en los enlaces firmados de los PDF de entradas, los archivos de calendario y las exportaciones CSV, y en la dirección de retorno de PayPal. |
REVALIDATE_SECRET | Opcional. El mismo valor que REVALIDATE_SECRET en el .env del sitio web. Con él, la API le dice al sitio web que reconstruya la página de un evento, recinto u organizador en cuanto se publica, se edita, se cancela o se agota; sin él, esas páginas se actualizan solas en el plazo de una hora. |
STOREFRONT_INTERNAL_URL | Opcional. Dónde llega la API al sitio web cuando difiere de STOREFRONT_URL, como dentro de Docker (http://storefront:3030). |
TICKET_SECRET | Opcional. Firma el código QR de cada entrada y los enlaces de descarga; si no se define, se usa JWT_SECRET. Defínelo una vez, antes de vender: cambiarlo después anula todos los códigos QR ya emitidos. |
EXPORT_DIR | Opcional. Dónde se escriben las exportaciones CSV antes de descargarlas, ./exports si no se define. |
TRUST_PROXY | Opcional. El número de proxies inversos delante de la API, para que los límites de inicio de sesión, formulario de contacto y escaneo de la puerta cuenten al visitante real. |
RATE_LIMIT_LOGIN | Opcional. Inicios de sesión fallidos que una dirección puede hacer en 15 minutos antes de 429, 10 por defecto. |
SEED_DEMO_DATA | Lo lee solo la imagen de Docker, en un volumen que aún no tiene base de datos: true la crea con los cuatro organizadores de ejemplo y sus cuentas, false solo con las tablas, tras lo cual la API crea tu propio espacio de trabajo a partir de las variables del propietario de abajo. |
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.
Tu propio espacio de trabajo y propietario
Se lee solo en una base de datos sin cuenta de personal ni espacio de trabajo (las tablas de yarn db:sync, o un volumen de Docker iniciado con SEED_DEMO_DATA=false). El primer inicio de la API crea entonces, a partir de ellas, los roles, los ajustes del sitio, las categorías de eventos, un espacio de trabajo y su propietario, una sola vez. En cuanto existe cualquier cuenta de personal, se ignoran.
OWNER_EMAIL=you@your-domain.com
OWNER_PASSWORD=a-long-password-of-your-own
OWNER_NAME=Your Name
WORKSPACE_NAME=Your organisation| Variable | Qué hace |
|---|---|
OWNER_EMAIL | El correo con el que el propietario inicia sesión en el panel. |
OWNER_PASSWORD | Al menos 10 caracteres. Con NODE_ENV=production, se rechazan el ejemplo de .env.example y la contraseña de las cuentas de ejemplo. Nunca se imprime y se puede quitar una vez que existe el propietario. |
OWNER_NAME | Opcional, Owner si no se define. Se cambia después en el perfil del propietario. |
WORKSPACE_NAME | Opcional, Ticketory si no se define. El nombre de tu organización, que se cambia después en Settings, General. |
En el Docker Compose de la pila completa pueden ir en el .env junto a docker-compose.yml, con SEED_DEMO_DATA=false: Compose pasa ese archivo primero a la API y luego back-end/.env, cuyo valor gana donde ambos definen uno. Sin las variables, la API arranca e indica cuáles definir.
Pagos
El pago envía al comprador a la página propia de Stripe o PayPal, así que los datos de la tarjeta nunca se escriben en tu sitio. Cada proveedor se ofrece en cuanto se definen sus claves. Usa primero claves de prueba: no mueven dinero.
STRIPE_SECRET_KEY=sk_test_your_key
STRIPE_WEBHOOK_SECRET=whsec_your_secret
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_WEBHOOK_ID=your-webhook-id
PAYPAL_ENV=sandbox| Variable | Qué hace |
|---|---|
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | Checkout alojado de Stripe. Una clave que empieza por sk_test_ o rk_test_ es modo de prueba. El webhook es https://<your-api>/api/webhooks/stripe, y envía checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed y refund.updated. |
PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, PAYPAL_WEBHOOK_ID | PayPal. El webhook es https://<your-api>/api/webhooks/paypal (PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, PAYMENT.CAPTURE.REFUNDED), y su id va en PAYPAL_WEBHOOK_ID. |
PAYPAL_ENV | sandbox o live. Sin definir significa sandbox. |
PAYMENTS_SIMULATOR | El pago de prueba, que paga un pedido sin mover dinero. auto (el valor por defecto) lo ofrece mientras no haya una clave real, así que las claves de prueba lo mantienen; on u off anulan eso. |
Las entradas gratuitas no necesitan nada de esto: un pedido sin nada que pagar se confirma al pagar, con o sin claves. Ticketory no cobra impuestos por sí mismo, así que configura los impuestos de tu país antes de aceptar pagos reales.
Correo electrónico
Las entradas, los códigos de registro, los restablecimientos de contraseña, las novedades de reembolso y los recordatorios de eventos se envían a través de Resend en cuanto se definen las dos variables. Hasta entonces, cada correo se escribe en el registro de la API, que es donde se lee un código de registro en una instalación nueva (con Docker: docker compose logs api).
RESEND_API_KEY=re_your_key
MAIL_FROM=Ticketory <tickets@your-domain.com>
EVENT_REMINDER_HOURS=24EVENT_REMINDER_HOURS es cuánto antes de un evento sale su recordatorio: 24 si no se define, como máximo 168 (una semana), y 0 desactiva los recordatorios. Todo correo sobre un pedido (entradas, reembolsos, el aviso de cancelación y el recordatorio) se escribe en el idioma en que se hizo el pedido.
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=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=
DB_DATABASE=ticketoryLuego ejecuta yarn seed para los datos de ejemplo, o yarn db:sync para las tablas sin datos. La API en marcha 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). La imagen de Docker lo hace sola solo en SQLite: en MySQL, ejecútalo tú una vez.
Imágenes y subidas
La API sirve ella misma las imágenes de ejemplo, desde public/media/ticketory (los símbolos de categoría, las marcas, el emblema del asistente y las fotos de ejemplo del estudio), en /media/ticketory/…. Las subidas desde el panel (las fotos de recintos vacíos para el estudio, las fotos adjuntas a una pregunta del asistente) y los conceptos terminados del estudio se guardan en el disco de la API bajo MEDIA_UPLOAD_DIR y se sirven en /media/uploads/…, salvo que se defina un bucket.
PUBLIC_MEDIA_URL=http://localhost:8000/media
MEDIA_UPLOAD_DIR=./public/media/uploadsPUBLIC_MEDIA_URL es la dirección en la que el navegador llega a /media. Cada dirección de imagen se construye a partir de ella, y la API traslada a ella las ya guardadas cuando arranca, así que mover la API conserva todas las imágenes. En un servidor, apunta MEDIA_UPLOAD_DIR a un almacenamiento persistente; con Docker está en el volumen de datos.
Para enviar las subidas a Cloudflare R2, o a cualquier bucket compatible con S3, define las cinco variables. Da a ambos frontends el host público del bucket mediante NEXT_PUBLIC_MEDIA_HOSTNAME (con Docker Compose, MEDIA_HOSTNAME) para que Next.js redimensione esas imágenes.
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.devLas imágenes se recodifican como JPEG al subirlas, con un máximo de 1920 píxeles de ancho. Los vídeos se aceptan como MP4, WebM, MOV o M4V, de hasta 150 MB.
Sitio web y panel del organizador
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 uno, y vuelve a construir (o reinicia yarn dev) 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_SITE_URL | Ambos | La dirección pública del sitio web, http://localhost:3030 por defecto. En el sitio web, de ella se construyen las URL canónicas, los idiomas alternativos, las tarjetas para compartir, robots.txt y el mapa del sitio; en el panel, el enlace "Ver sitio web" y las vistas previas de eventos. |
NEXT_PUBLIC_DASHBOARD_URL | Ambos | La dirección del panel. En el sitio web, adonde "Sell tickets" y los enlaces de organizador envían a un organizador a iniciar sesión (http://localhost:3031). En el panel, la base de la imagen que se muestra al compartir un enlace del panel; vacío usa domain.url en src/config/brand.config.ts. |
NEXT_PUBLIC_MEDIA_HOSTNAME | Ambos | Opcional. Los hosts https que sirven las imágenes, separados por comas: el host público de tu bucket, como pub-1234.r2.dev, el dominio de la API, o ambos. Next.js redimensiona las imágenes que están en ellos; cualquier otra imagen se carga tal cual. Solo hosts, sin https://. Déjalo vacío mientras la API se ejecute en localhost. |
NEXT_PUBLIC_WEBSOCKET_BASE_URL | Panel | La dirección de la API sin /api, para las notificaciones en tiempo real. |
NEXT_PUBLIC_MAP_STYLE_LIGHT, NEXT_PUBLIC_MAP_STYLE_DARK | Panel | Estilos de teselas del mapa opcionales. Sin definir, el tema claro dibuja el estilo Positron de OpenFreeMap y el tema oscuro su estilo Dark, que no necesitan clave. |
NEXT_PUBLIC_PLACE_SEARCH_URL | Panel | La búsqueda de lugares del selector de mapa del editor de recintos, https://photon.komoot.io/api si no se define. Sirve cualquier geocodificador que responda con la misma forma. |
REVALIDATE_SECRET | Sitio web | Solo servidor, se lee al ejecutarse. El secreto que la API envía al POST /api/revalidate del sitio web después de que cambie un evento; el mismo valor que en el .env de la API. Vacío, esa ruta rechaza todas las llamadas y las páginas se actualizan en el plazo de una hora. |
API_INTERNAL_URL | Sitio web | Opcional, solo servidor, se lee al ejecutarse. Dónde llega el propio servidor del sitio web a la API (títulos de las páginas de evento, el primer renderizado de las páginas de evento y recinto, el mapa del sitio) cuando la dirección del navegador no funciona desde dentro, como en Docker (http://api:8000/api en Docker Compose). Déjalo sin definir en otros casos. |
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_*: Google Tag Manager (NEXT_PUBLIC_GTM_ID), GA4 (NEXT_PUBLIC_GA4_MEASUREMENT_ID), Meta, TikTok, Snapchat y Pinterest, cada una activada con un solo id; un id en blanco no carga ningún script. NEXT_PUBLIC_ANALYTICS_CURRENCY (USD por defecto) es la moneda que se envía con los precios de las entradas, y NEXT_PUBLIC_ANALYTICS_DEBUG=true registra cada evento rastreado en la consola del navegador.
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 | Valor 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 | Los hosts https que sirven las imágenes, separados por comas: el host público de tu bucket (con las variables R2_* de back-end/.env), el propio dominio de la API, o ambos. |
REVALIDATE_SECRET | Un valor local | El secreto que comparten la API y el sitio web, para que un cambio hecho en el panel llegue al instante a las páginas del sitio web. Define tu propio valor largo y aleatorio en un servidor abierto a internet. |
SEED_DEMO_DATA | true | false empieza con tablas vacías en lugar de los cuatro organizadores de ejemplo, y con las variables del propietario definidas la API crea entonces tu propio espacio de trabajo y su propietario. Solo importa en un volumen nuevo. |
OWNER_EMAIL, OWNER_PASSWORD, OWNER_NAME, WORKSPACE_NAME | Vacío | El propietario y el nombre de tu espacio de trabajo, que se leen solo en una base de datos sin cuenta de personal: mira Tu propio espacio de trabajo y propietario, arriba. |
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, NEXT_PUBLIC_ANALYTICS_DEBUG | USD, false | La moneda que se envía con cada precio registrado, y el registro de cada evento en la consola del navegador. |
NEXT_PUBLIC_MAP_STYLE_LIGHT, NEXT_PUBLIC_MAP_STYLE_DARK, NEXT_PUBLIC_PLACE_SEARCH_URL | Vacío | Las teselas del mapa y la búsqueda de lugares del panel; vacío usa OpenFreeMap y Photon. |
Cambia un puerto cuando otro programa ya lo usa, por ejemplo ADMIN_PORT=3041. CORS_ORIGIN, FRONTEND_URL, STOREFRONT_URL, PUBLIC_API_URL y PUBLIC_MEDIA_URL de la API, y las direcciones de la API, el sitio web y el panel de los frontends, se construyen todos a partir de los puertos y las tres direcciones, así que siguen solos.
El contenedor de la API lee primero este .env y luego back-end/.env cuando existe, cuyo valor gana donde ambos definen uno, así que las claves opcionales se definen en un solo lugar para yarn dev y para Docker. El archivo compose gana en los valores que difieren dentro de un contenedor: la ruta de la base de datos, las carpetas de subidas y exportaciones, el puerto, NODE_ENV=production y las direcciones de arriba. La base de datos, las subidas y las exportaciones CSV viven en el volumen ticketory-data.
Funciones de IA
Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.
Activar el asistente de eventos con IA y el estudio de recintos con IA: las claves de proveedor y el modelo de imagen.
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.
El interruptor de una demostración pública, y por qué permanece desactivado para un organizador real.