Ir al artículo
Aniq-UI

NorthstackVariables 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.
website/.envEl sitio web: los valores NEXT_PUBLIC_* al construir, API_INTERNAL_URL en su servidorNo. Cada valor es público o una dirección.
dashboard/.envEl panel, al construir, y su PORT cuando empieza yarn dev o yarn startNo. Todos los valores son públicos.
.env junto a docker-compose.ymlSolo Docker Compose: los puertos y las direcciones con las que construye las tres aplicacionesNo.

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 archivo, .env en la carpeta del sitio web, y todos sus valores son opcionales. Los valores NEXT_PUBLIC_* se leen cuando se construye el sitio web y son públicos, así que nunca guardan un secreto; API_INTERNAL_URL lo lee el propio servidor del sitio web. Sin el archivo, el sitio funciona con sus datos de ejemplo integrados. Para usar una API, créalo a partir de .env.example, que apunta a una en http://localhost:8000: cp .env.example .env. Con Docker, pasa los valores NEXT_PUBLIC_* como --build-arg y API_INTERNAL_URL con -e.

Dónde están los ajustes

Un archivo, .env en la carpeta del panel, que se lee cuando se construye el panel y, para PORT, cuando empieza yarn dev o yarn start. Todos sus valores son públicos, así que nunca guarda un secreto: las claves de proveedores y de pago viven en el .env de la API. Sin el archivo, el panel funciona con sus datos de ejemplo integrados. Para usar una API, créalo a partir de .env.example, que apunta a una en http://localhost:8000: cp .env.example .env. Con Docker, pasa los mismos valores como --build-arg.

Dónde están los ajustes

Un archivo, .env en la carpeta de la API, que la API lee con yarn dev, yarn start:prod y yarn seed. Contiene secretos: nunca lo subas al repositorio. 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: NODE_ENV=production, SQLite en /data/database.sqlite, archivos subidos en /data/uploads, CORS_ORIGIN para los dos frontends locales, FRONTEND_URL y DASHBOARD_URL definidos como http://localhost:3031, WEBSITE_URL=http://localhost:3030, PUBLIC_API_URL=http://localhost:8000 y PUBLIC_MEDIA_URL=http://localhost:8000/media. Sustituye cualquiera con -e.

Lo esencial de la API

La API comprueba JWT_SECRET y, en producción, CORS_ORIGIN antes de iniciar. Si falta uno o no sirve, se detiene con una línea que empieza por The API cannot start: y dice qué corregir.

VariableQué hace
NODE_ENVdevelopment en local, que crea y actualiza las tablas al iniciar. production en un servidor en vivo, que nunca toca las tablas y rechaza el JWT_SECRET de ejemplo y un CORS_ORIGIN vacío.
PORTEl puerto de la API, 8000. Ambos frontends apuntan a él.
DB_TYPEsqlite (el valor por defecto si no se define) o mysql.
SQLITE_DATABASERuta del archivo SQLite, ./database.sqlite, relativa a la carpeta de la API.
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 si no se define. El formulario de inicio de sesión del panel lo sustituye: con Remember me marcado firma un inicio de sesión de 30 días, sin marcar uno de 12 horas.
CORS_ORIGINLas 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_URLLa dirección del panel, el único origen que aceptan sus actualizaciones de permisos en vivo, http://localhost:3031 si no se define.
DASHBOARD_URLLa dirección del panel en los enlaces que escribe la API: invitaciones, restablecimientos de contraseña y la página a la que vuelve el pago de un plan. http://localhost:3031 si no se define.
WEBSITE_URLLa dirección del sitio web: Stripe y PayPal devuelven a ella a los compradores de licencias. http://localhost:3030 si no se define.
PUBLIC_API_URLLa propia dirección pública de la API, usada en los enlaces firmados de descarga de facturas.
RATE_LIMIT_LOGINLos inicios de sesión fallidos que una dirección puede hacer en 15 minutos antes de recibir 429, 10 por defecto.
TRUST_PROXYEl número de proxies inversos delante de la API (1 detrás de Nginx, Caddy o un balanceador de carga; 2 con Cloudflare delante de ese proxy), para que el límite de inicios de sesión y los límites por dirección de la demo cuenten visitantes y no un proxy. La dirección se lee desde la derecha de X-Forwarded-For, así que un cliente no puede elegirla. Déjalo vacío cuando se llega a la API directamente.
ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_NAMEEl primer administrador de la plataforma que crea yarn admin:create, para empezar sin las cuentas de ejemplo. El comando pide un correo o una contraseña vacíos; el nombre es Platform Admin cuando está vacío.
SEED_SAMPLE_DATASolo Docker. true (el valor por defecto) carga un volumen nuevo con los datos de ejemplo y los inicios de sesión publicados. false lo inicia vacío: las tablas, más el primer administrador de la plataforma cuando ADMIN_EMAIL y ADMIN_PASSWORD están definidos. Con Docker Compose va en el archivo .env junto a docker-compose.yml, con ADMIN_EMAIL y ADMIN_PASSWORD; Compose pasa estos tres desde allí, así que en back-end/.env solo los leen los comandos yarn.

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 variables en .env.example sigan vacías.

Pagos

Dos flujos mueven dinero. La página de facturación del panel cambia el plan de suscripción de un espacio de trabajo, y el pago del sitio web vende las licencias. Ambos piden los datos de la tarjeta solo en la página de Stripe o de PayPal (un cambio a un plan superior se cobra a la tarjeta que Stripe ya tiene), así que nunca se escriben en tu sitio, y ambos funcionan sin ninguna cuenta mediante pagos de prueba integrados que no cobran a nadie. Usa primero claves de prueba: no mueven dinero.

El .env de la API
STRIPE_SECRET_KEY=sk_test_your_key
STRIPE_WEBHOOK_SECRET=whsec_your_secret
BILLING_PROVIDER=
BILLING_GRACE_DAYS=7
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_ENV=sandbox
VariableQué hace
STRIPE_SECRET_KEYStripe, para ambos flujos. Con él, un primer pago abre Stripe Checkout, un cambio a un plan superior de una suscripción activa se cobra a la tarjeta guardada, un cambio a uno inferior se programa en la suscripción, y Manage payment method abre el portal de clientes de Stripe, y una tarjeta en el pago de licencias paga en la página alojada de Stripe. Una clave que empieza por sk_test_ es modo de prueba; con una clave sk_live_ los cambios de plan cobran tarjetas reales.
STRIPE_WEBHOOK_SECRETVerifica el único webhook que comparten ambos flujos, https://<your-api>/api/billing/webhooks/stripe, con los eventos checkout.session.completed, checkout.session.expired, invoice.paid, invoice.payment_failed y customer.subscription.deleted. Cada evento se aplica una sola vez. Con STRIPE_SECRET_KEY definido y este vacío, el registro de la API lo indica al iniciar y cada entrega se rechaza con un 400 que nombra la variable, así que las renovaciones, los pagos fallidos y las cancelaciones no se registran.
BILLING_PROVIDERVacío elige Stripe cuando su clave está definida y el pago de prueba en caso contrario. simulator fuerza el pago de prueba incluso con claves.
BILLING_GRACE_DAYSDías durante los que un espacio de trabajo con pago vencido, o cuya prueba terminó sin pagar, aún puede crear proyectos, invitaciones y claves de API, 7 por defecto. La lectura siempre sigue funcionando, y no se elimina nada por un pago fallido.
PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRETUna aplicación REST de PayPal, para PayPal en el pago de licencias. El pago se captura cuando el comprador vuelve.
PAYPAL_ENVsandbox (el valor por defecto, sin dinero real) o live.

En tu propio equipo Stripe no puede llegar al webhook, así que las páginas de retorno piden la sesión a Stripe por sí mismas y un pago de prueba se completa igualmente. Un plan o una licencia cuenta como pagado solo cuando la API lo ha verificado con el proveedor, nunca por la dirección de retorno sola. Northstack no cobra impuestos por sí mismo, así que configura los impuestos de tu país antes de aceptar pagos reales.

Correo electrónico

Las invitaciones, los restablecimientos de contraseña, los recibos de licencia, los correos de facturación y el resumen semanal se envían por SMTP cuando se define SMTP_HOST, cada uno en el idioma del destinatario (el del espacio de trabajo cuando no ha elegido ninguno). Hasta entonces cada mensaje se escribe en el registro de la API, con sus enlaces, para que una instalación local pueda seguirlos (con Docker: docker compose logs api).

El .env de la API
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-smtp-user
SMTP_PASSWORD=your-smtp-secret
SMTP_FROM=Northstack <no-reply@your-domain.com>
CONTACT_INBOX=hello@your-domain.com

SMTP_SECURE=true es para un servidor que habla TLS desde el primer byte, normalmente en el puerto 465. CONTACT_INBOX es adonde se reenvían los mensajes del formulario de contacto del sitio web; vacío los guarda solo en la base de datos.

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=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=your-database-secret
DB_DATABASE=northstack

Luego ejecuta yarn seed, que crea las tablas y los datos de ejemplo. La API en marcha solo crea y actualiza las tablas por sí sola cuando NODE_ENV=development, así que con NODE_ENV=production ejecuta yarn admin:create:prod una vez tras yarn build para las tablas y tu primer administrador de la plataforma (yarn seed:prod para una instalación de ejemplo), y yarn schema:prod tras cada actualización. La imagen de Docker crea la base de datos por sí sola solo en SQLite: en MySQL, ejecuta tú mismo node dist/database/create-admin.js (o node dist/database/seeder.js) una vez en el contenedor.

Archivos subidos y multimedia

La API sirve por sí misma los archivos de marca del kit en /media. Los archivos e imágenes de proyectos subidos desde el panel, de hasta 10 MB cada uno, se guardan en el disco de la API bajo MEDIA_UPLOAD_DIR y se sirven en /media/uploads/…, salvo que se defina un bucket.

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 a la que un navegador llega a /media. En un servidor, apunta MEDIA_UPLOAD_DIR a un almacenamiento persistente; con Docker está en el volumen de datos, y el contenedor mueve allí por sí solo una carpeta relativa. La API envía todos los archivos con nosniff, y un archivo que no sea una imagen, un PDF, texto plano, audio o vídeo como descarga.

Para enviar los archivos subidos a un bucket de Cloudflare R2, define las cinco variables. Con menos de cinco, los archivos siguen en el disco. El registro de la API indica el almacenamiento que usa al iniciar: Media storage: R2 bucket seguido del nombre del bucket, o Media storage: local folder seguido de la carpeta.

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

Sitio web y panel

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) tras cambiar uno. Con Docker, pásalos como --build-arg.

NEXT_PUBLIC_API_BASE_URL decide de dónde vienen los datos de cada frontend. Vacío, o sin ningún .env, la aplicación funciona con sus datos de ejemplo integrados y no llama a ninguna API. Definido con la dirección de la API incluido /api (http://localhost:8000/api en .env.example y en las imágenes de Docker), usa esa API, y recurre a los datos de ejemplo solo en el navegador mientras esa API no responde.

Los ajustes del sitio web

VariableValor por defectoQué hace
NEXT_PUBLIC_SITE_URLhttp://localhost:3030La dirección pública de este sitio: de ella se construyen los enlaces canónicos, las alternativas de idioma, el mapa del sitio y las tarjetas para compartir. Defínela con tu dominio antes de publicar.
NEXT_PUBLIC_API_BASE_URLVacío sin .envLa API de Northstack, incluido /api, para el formulario de contacto y el pago de licencias.
API_INTERNAL_URLVacíoOpcional, lo lee en tiempo de ejecución solo el servidor del sitio web, para el pago y su recibo renderizados en el servidor. Vacío usa NEXT_PUBLIC_API_BASE_URL. En Docker, defínelo con la dirección de la API tal como la alcanza el contenedor (http://api:8000/api en Docker Compose).
NEXT_PUBLIC_DASHBOARD_URLhttp://localhost:3031El panel. Live demo, Explore the demo, See role controls y Sign in en /error/401 lo abren, y /auth/signin, /auth/signup y /auth/forgot-password del sitio pasan a sus páginas.
NEXT_PUBLIC_PURCHASE_URL_SINGLE, NEXT_PUBLIC_PURCHASE_URL_STUDIOVacíoLa página de pago de una tienda externa para cada licencia. Vacío mantiene el pago propio del sitio en /checkout.
NEXT_PUBLIC_SAMPLE_DATA_NOTICEVacíoalways muestra el aviso de datos de ejemplo en una versión de producción mientras la API definida arriba no responde; con Docker, --build-arg NEXT_PUBLIC_SAMPLE_DATA_NOTICE=always. Siempre se muestra en desarrollo, y en toda construcción hecha sin API.
BUILD_STANDALONEVacíotrue hace que yarn build genere un servidor autónomo en .next/standalone, lo que define el Dockerfile. Déjalo vacío para yarn start.

El puerto del sitio web es 3030, escrito en los scripts de su package.json. Para otro, ejecuta yarn next dev -p 3040 (o yarn next start -p 3040 tras yarn build).

Los ajustes del panel

VariableValor por defectoQué hace
PORT3031El puerto que usan yarn dev y yarn start. scripts/next-with-port.mjs lo lee de .env y se lo pasa a Next.js.
NEXT_PUBLIC_API_BASE_URLVacío sin .envLa API de Northstack, incluido /api. Todas las pantallas hablan con ella.
NEXT_PUBLIC_WEBSOCKET_BASE_URLLa dirección de la API sin /apiEl servidor de la API, para las actualizaciones de permisos en vivo.
NEXT_PUBLIC_BASE_URLhttp://localhost:3031La dirección pública de este panel: robots.txt, el mapa del sitio, la dirección del espacio de trabajo que se muestra en el alta inicial y las direcciones absolutas de los metadatos.
NEXT_PUBLIC_WEBSITE_URLhttp://localhost:3030El sitio web público: el enlace Documentation de la barra lateral y los enlaces Privacy y Terms de la página de inicio de sesión.
BUILD_STANDALONESin definirtrue hace que yarn build genere un servidor autónomo, lo que configura el Dockerfile. En otro caso, déjalo sin configurar.

Aquí no va ninguna clave de proveedor de IA ni de pago: un valor NEXT_PUBLIC_* es visible para cualquiera que abra la página. Un proveedor para el que la API no tiene clave aún se puede usar con una clave que quien lee añade en el propio asistente.

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.

VariableValor por 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 alcanza el navegador a cada aplicación. Define las tres al servir la pila en tus propios dominios, como API_URL=https://api.your-domain.com.
PURCHASE_URL_SINGLE, PURCHASE_URL_STUDIOVacíoEl pago de una tienda externa para cada licencia, si vendes a través de una; vacío mantiene el pago propio del sitio web.
SEED_SAMPLE_DATAtrueSe lee solo en el primer inicio de un volumen nuevo: true carga los datos de ejemplo, false lo inicia vacío.
ADMIN_EMAIL, ADMIN_PASSWORDVacíoCon SEED_SAMPLE_DATA=false, el primer administrador de la plataforma creado en el primer inicio; vacío crea solo las tablas.

Cambia un puerto cuando otro programa ya lo usa, como ADMIN_PORT=3041. El CORS_ORIGIN, FRONTEND_URL, DASHBOARD_URL, WEBSITE_URL, PUBLIC_API_URL y PUBLIC_MEDIA_URL de la API, y las direcciones de API, sitio web y panel de los frontends, se construyen todos a partir de los puertos y las tres direcciones, así que los siguen por sí solos.

El contenedor de la API también lee back-end/.env cuando existe, así que las claves opcionales (Stripe, PayPal, correo, R2, IA, MCP) se definen en un solo lugar para yarn dev y para Docker. docker-compose.yml prevalece en los valores que difieren dentro de un contenedor: NODE_ENV=production, el puerto, la ruta de la base de datos, la carpeta de archivos subidos y las direcciones de arriba. Sin un JWT_SECRET propio, o con el de ejemplo, la API genera uno y lo guarda en el volumen de datos. La base de datos y los archivos subidos viven en el volumen northstack-data.

Claves del asistente de IA

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

Activar el asistente del espacio de trabajo en el servidor: las claves de los proveedores y quién paga cada mensaje.

El servidor MCP

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

Dejar que los agentes de código usen las herramientas del espacio de trabajo: la clave, el espacio de trabajo 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é se queda desactivado en un producto real.

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