Ir al artículo
Aniq-UI

LearnioVariables 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 DockerSí. Nunca lo incluyas en un commit.
frontend/.envEl sitio para estudiantes, durante la construcciónNo. Todos los valores son públicos.
admin-dashboard/.envEl panel de administración, durante la construcciónNo. Todos los valores son públicos.
.env junto a docker-compose.ymlDocker Compose, para el paquete Full StackNo

Crea cada archivo a partir del .env.example que tiene al lado, que documenta todas las variables: cp .env.example .env. Los ejemplos funcionan tal cual para una ejecución local.

Dónde están los ajustes

Un solo archivo, frontend/.env, que se lee al construir el sitio. Todos sus valores son públicos, así que nunca contiene un secreto. Créalo a partir de .env.example, que documenta cada variable: cp .env.example .env.

Dónde están los ajustes

Un solo archivo, admin-dashboard/.env, que se lee al construir el panel. Todos sus valores son públicos, así que nunca contiene un secreto. Omítelo para usar la simulación; créalo a partir de .env.example cuando conectes una API: cp .env.example .env.

Dónde están los ajustes

Un solo archivo, back-end/.env, que la API lee con yarn dev y dentro de Docker. Contiene secretos: nunca lo incluyas en 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.

Lo esencial de la API

La API comprueba estas variables antes de iniciarse. Si falta alguna o no es válida, se detiene con una lista breve de lo que hay que corregir.

VariableQué hace
NODE_ENVdevelopment en local, production en un servidor en producción.
PORTEl puerto de la API, 8000. Ambos frontends apuntan a él.
DB_TYPEsqlite (el predeterminado) o mysql.
SQLITE_DATABASERuta del archivo SQLite, ./database.sqlite por defecto.
JWT_SECRETFirma cada inicio de sesión. Obligatorio. El valor de ejemplo solo se acepta en desarrollo.
JWT_EXPIRATIONCuánto dura un inicio de sesión, 7d por defecto.
CORS_ORIGINLas direcciones del sitio para estudiantes y del panel de administración, separadas por comas. Obligatorio en producción.
FRONTEND_URLLa dirección del sitio para estudiantes, usada en los enlaces que envía la API.

Genera tu propio JWT_SECRET con:

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

Usa MySQL en lugar de SQLite

Crea una base de datos vacía y luego configura el controlador y la conexión en back-end/.env:

back-end/.env
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

Después ejecuta yarn seed para los datos de demostración, o yarn db:sync en un sitio en producción, que crea las tablas sin escribir ninguna fila. La API en ejecución solo actualiza el esquema por sí misma cuando NODE_ENV=development.

Sitio para estudiantes y panel de administración

Todos los valores de aquí son NEXT_PUBLIC_* y se compilan en el JavaScript que carga el navegador. Nunca pongas un secreto en estos archivos, y vuelve a construir la aplicación después de cambiar uno.

VariableAplicaciónQué hace
NEXT_PUBLIC_API_BASE_URLAmbosLa dirección de la API incluyendo /api, por ejemplo http://localhost:8000/api. Si se deja vacía, la aplicación usa sus datos de ejemplo.
NEXT_PUBLIC_SITE_URLAmbosLa dirección pública del sitio para estudiantes, usada para los enlaces canónicos, las vistas previas al compartir y el mapa del sitio. En producción, pon tu dominio real.
NEXT_PUBLIC_MEDIA_HOSTNAMEAmbosEl host público de tu bucket de archivos multimedia, sin https://. Déjalo vacío hasta que tengas un bucket.
NEXT_PUBLIC_WEBSOCKET_BASE_URLPanel de administraciónLa dirección de la API sin /api, para las notificaciones en tiempo real.
NEXT_PUBLIC_SAMPLE_DATA_NOTICEAmbosOpcional. always muestra el aviso "Sample data" también en una versión de producción cuando la API deja de responder. El docker-compose.yml de la raíz lo define; un sitio en producción normalmente lo deja sin definir.
API_INTERNAL_URLSitio para estudiantesOpcional, solo en el servidor. La dirección por la que el propio servidor del sitio llega a la API cuando difiere de la del navegador, como dentro de Docker Compose.

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 compilan estos valores en su código.

VariableQué hace
SITE_PORT, ADMIN_PORT, API_PORTLos puertos de tu ordenador: 3030, 3031 y 8000 por defecto. Pon uno cuando otro programa ya use ese puerto, por ejemplo ADMIN_PORT=3041. Las direcciones de abajo, CORS_ORIGIN y FRONTEND_URL los siguen.
SITE_URL, ADMIN_URL, API_URLDónde llega el navegador a cada aplicación. Configura las tres cuando sirvas el conjunto en tus propios dominios.
MEDIA_HOSTNAMEEl host público de tu bucket, junto con las variables R2_* en back-end/.env.
SEED_DEMO_DATAfalse empieza con las tablas vacías en lugar de los datos de demostración.

El contenedor de la API también lee back-end/.env cuando existe, así que las claves de correo, pagos, archivos multimedia e IA se configuran en un solo lugar tanto para yarn dev como para Docker.

Almacenamiento multimedia

Las imágenes de los cursos, los avatares, las imágenes del blog, los videos de las lecciones y los materiales se suben a un bucket de Cloudflare R2, o a cualquiera compatible con S3. Configura las cinco variables en back-end/.env y da a ambos frontends el host público del bucket mediante NEXT_PUBLIC_MEDIA_HOSTNAME.

back-end/.env
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_ENDPOINT=
R2_BUCKET_NAME=
R2_PUBLIC_URL=

Sin un bucket, el script de carga de datos guarda rutas a archivos de ejemplo que incluyen los propios frontends, así que todas las imágenes y los videos de las lecciones funcionan en local. Solo deja de funcionar la subida de nuevos archivos multimedia.

Correo electrónico

Las confirmaciones de email, los restablecimientos de contraseña, los recibos y las confirmaciones de inscripción se envían a través de Resend. Sin RESEND_API_KEY, la aplicación sigue funcionando y escribe cada mensaje en su registro.

back-end/.env
RESEND_API_KEY=
MAIL_FROM=Learnio <noreply@example.com>
MAIL_MAX_PER_ADDRESS_PER_DAY=5
MAIL_MAX_PER_SENDER_PER_DAY=20
  • Usa una clave con acceso solo de envío, no una con acceso completo.
  • MAIL_FROM debe pertenecer a un dominio que hayas verificado en Resend; de lo contrario, se rechaza cada envío.
  • Los dos límites fijan cuántos mensajes al día puede recibir una dirección y cuántos puede provocar un mismo remitente.
  • El nombre del producto dentro de cada mensaje y su dirección de respuesta no son variables: son los ajustes site_name y support_email de la pestaña App Settings de Settings, en el panel de administración, y se leen para cada mensaje que se envía.

Pagos

De serie, el pago funciona con un simulador integrado: no se contacta con ningún procesador y no se cobra nada. Un número de tarjeta que termina en 0 se rechaza, para que puedas probar el caso de fallo.

Rellena las claves de un procesador y ese método de pago pasa al procesador real. Configura tanto Stripe como PayPal antes de aceptar pedidos reales: el pago siempre ofrece tarjeta y PayPal, y un pedido pagado con el simulador se completa sin que se cobre a nadie.

Los cursos gratuitos (precio 0) no necesitan ningún procesador: su pago se completa en la API sin él, sean cuales sean las claves definidas.

ProcesadorVariablesEndpoint del webhook
StripeSTRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRETPOST <api>/api/webhooks/payments/stripe
PayPalPAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, PAYPAL_WEBHOOK_ID, PAYPAL_ENVPOST <api>/api/webhooks/payments/paypal

El webhook concede la plaza

Un estudiante queda inscrito cuando el procesador confirma el pago a través del webhook, no cuando vuelve de la página de pago. Sin la suscripción al webhook, los pedidos se quedan pendientes.

  • Suscribe Stripe a checkout.session.completed, payment_intent.payment_failed y charge.refunded.
  • Suscribe PayPal a PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, PAYMENT.CAPTURE.REFUNDED y PAYMENT.CAPTURE.REVERSED.
  • PAYPAL_ENV es sandbox por defecto, que no cobra dinero real. Las credenciales de producción pertenecen a otra app de PayPal, así que pasar a producción requiere claves nuevas además de PAYPAL_ENV=live.

Asistente de IA

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Activar el asistente de IA: las claves de los proveedores, cómo se ofrece cada modelo y qué ve el administrador sin clave.

Clases en vivo

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Configurar las clases en directo: conectar un servidor Jitsi Meet, los tokens de acceso seguros y los controles del anfitrión.

Datos de ejemplo en los frontends

Ambos frontends siguen funcionando cuando no se puede acceder a la API: sirven los datos de ejemplo incluidos y muestran un aviso "Sample data" al pie de la página. En una versión de producción solo aparece cuando no hay ninguna API configurada, salvo que la app se haya compilado con NEXT_PUBLIC_SAMPLE_DATA_NOTICE=always, como hace el docker-compose.yml de la raíz.

  • Los datos de ejemplo del panel de administración cubren el inicio de sesión, los estudiantes, el personal, los roles, las categorías, los ajustes, las notificaciones, la búsqueda y el historial de chats del asistente. Sus demás pantallas (las cifras del resumen, cursos, instructores, inscripciones, pedidos, reseñas, blog, agenda, cuestionarios y mensajes) necesitan la API.
  • Con los datos de ejemplo, el inicio de sesión del panel de administración acepta cualquier correo y contraseña, y guarda tus cambios en el navegador. Para empezar de cero, ejecuta localStorage.removeItem("mock_db_v1"); location.reload(); en la consola del navegador.
  • El asistente de IA no está disponible con los datos de ejemplo, porque necesita las claves de la API.
  • Cuando tu API esté en producción, yarn remove:mock en cualquiera de las dos aplicaciones elimina la capa de datos de ejemplo.

Cómo funciona la capa de datos de ejemplo

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Cómo se dirigen las solicitudes a los datos incluidos, y cómo cambiarlos o ampliarlos.

Modo demostración

Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.

Publicar una demo: el interruptor de la demo, las cuentas por visitante, el límite de mensajes y cómo quitarlo todo.

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