Ir al artículo
Aniq-UI

VelraDespliega la agencia

Despliega la agencia

Pon en línea el sitio web, el panel y la API: Docker Compose en un servidor, una aplicación por host desde su Dockerfile, o Node.js sin más.

Para el paquete Full Stack

Tres formas de desplegar

FormaIdeal paraQué necesitas
Docker Compose en un servidorUn VPS que controlas, las tres aplicaciones juntasEl paquete Full Stack, Docker en el servidor, un proxy inverso para HTTPS
Una aplicación por host, desde su DockerfileRailway, Render, Fly.io y otros hosts que construyen desde un DockerfileLa carpeta de cada aplicación; un volumen o MySQL y un bucket para la API
Node.js sin másCualquier host con NodeNode.js 22 o más reciente y Yarn 4 en el host

Elijas la forma que elijas, el sitio web y el panel compilan la dirección de la API en su JavaScript cuando se construyen, así que constrúyelos con las direcciones públicas, nunca con las locales.

Docker Compose en un servidor

Copia la carpeta del paquete al servidor y pon un .env junto a docker-compose.yml con las tres direcciones públicas. De ellas se derivan los orígenes permitidos de la API, la dirección del panel, las direcciones de las fotos y la dirección de la API de los frontends.

.env junto a docker-compose.yml
SITE_URL=https://www.your-agency.com
ADMIN_URL=https://admin.your-agency.com
API_URL=https://api.your-agency.com
MEDIA_HOSTNAME=api.your-agency.com

MEDIA_HOSTNAME es opcional, un host o varios separados por comas (añade el host de tu bucket cuando las subidas vayan a uno): las fotos en esos hosts https las redimensiona Next.js, y cualquier otra foto se carga tal cual. Luego construye e inicia en segundo plano:

Terminal
docker compose up --build -d
  • Apunta cada dominio al servidor mediante un proxy inverso que sirva HTTPS (Caddy, Nginx o Traefik), reenviando a los puertos 3030, 3031 y 8000.
  • Detrás de ese proxy, define TRUST_PROXY=1 en back-end/.env, para que los límites de inicio de sesión, formulario de contacto y solicitud de visita cuenten a cada visitante y no al proxy. El contenedor de la API lee back-end/.env cuando existe, que es también donde van las claves opcionales.
  • Sin un JWT_SECRET propio, la API genera uno en su primer inicio y lo guarda en el volumen velra-data. La base de datos y las subidas también están en ese volumen, así que haz una copia de seguridad.
  • El primer inicio carga la agencia de demostración salvo que SEED_DEMO_DATA=false esté en el .env. Mantenlo en el primer inicio: la carga inicial es lo que crea las cuentas.

La API desde su Dockerfile

Apunta el host a la carpeta de la API (back-end/ en el Full Stack). La imagen escucha en PORT (8000 salvo que el host defina otro), responde a GET /api/health cuando su base de datos responde, y guarda SQLite y las subidas en /data.

  • Monta un volumen persistente en /data. Sin uno, cada despliegue empieza con una base de datos vacía.
  • Define CORS_ORIGIN con las direcciones del sitio web y del panel (separadas por comas), FRONTEND_URL con la del panel y PUBLIC_MEDIA_URL con la dirección pública de la API seguida de /media.
  • Define SEED_DEMO_DATA=true para el primer inicio en un volumen nuevo: el valor por defecto de la imagen es false, que crea las tablas sin cuentas. Una base de datos existente nunca se vuelve a cargar.
  • Define tu propio JWT_SECRET, o deja que el contenedor genere uno y lo guarde en /data/.jwt-secret.
  • Define TRUST_PROXY=1: una plataforma de alojamiento pone un proxy delante del contenedor.
  • Con MySQL (DB_TYPE=mysql y las cinco variables DB_*), el contenedor no crea las tablas. Ejecuta una vez node dist/database/seeder.js (agencia de demostración) o node dist/database/sync-schema.js (tablas vacías) con el mismo entorno.
  • Las subidas en el volumen sobreviven a un nuevo despliegue; para mantenerlas fuera del servidor, define las cinco variables R2_* para un bucket.

El sitio web y el panel desde sus Dockerfiles

Apunta el host a la carpeta de la aplicación y dale los valores NEXT_PUBLIC_* como argumentos de construcción, no como variables de ejecución: se compilan dentro. Cada imagen sirve el servidor independiente de Next.js en PORT (3030 para el sitio web, 3031 para el panel, salvo que el host defina otro).

Argumento de construcciónAplicaciónValor
NEXT_PUBLIC_API_BASE_URLAmbosLa dirección pública de la API seguida de /api
NEXT_PUBLIC_SITE_URLAmbosLa dirección pública del sitio web: las URL canónicas y el mapa del sitio en el sitio web, el enlace "View website" en el panel
NEXT_PUBLIC_MEDIA_HOSTNAMEAmbosOpcional. Los hosts https que sirven las fotos (el dominio de la API, el de tu bucket, o ambos), separados por comas
NEXT_PUBLIC_WEBSOCKET_BASE_URLPanelLa dirección pública de la API sin /api, para las notificaciones en directo

El servidor del sitio web también consulta la API mientras renderiza las páginas de propiedad y el mapa del sitio. Con una dirección pública de la API que funcione también desde el servidor, no hace falta nada más; API_INTERNAL_URL en tiempo de ejecución la sustituye cuando el servidor debe usar otra dirección.

Node.js sin más

Construye cada aplicación una vez en el host y luego inicia. Define el .env de los frontends con las direcciones públicas antes de yarn build.

AplicaciónConstrucciónInicio
APIyarn build, y una vez yarn seed:prod (agencia de demostración) o yarn db:sync:prod (tablas vacías)yarn start:prod
Sitio web públicoyarn buildyarn start (puerto 3030)
Panel de la agenciayarn buildyarn start (puerto 3031)

La API se enlaza a 0.0.0.0 y lee PORT. Mantén el archivo SQLite y MEDIA_UPLOAD_DIR en un almacenamiento que sobreviva a un despliegue, o usa MySQL y un bucket.

Tus primeras cuentas

No hay página de registro: las dos cuentas del panel vienen de la carga inicial. Empieza la primera vez con la agencia de demostración, inicia sesión y luego hazla tuya:

  1. Cambia ambas contraseñas en Ajustes, Seguridad, o crea tu propio Super Admin en Gestión de administradores y elimina las cuentas de la carga inicial.
  2. Archiva o elimina las propiedades de ejemplo, y elimina los barrios de ejemplo que no necesites.
  3. Cierra las consultas de ejemplo y cancela las visitas de ejemplo: no se pueden eliminar.
  4. Define el nombre, el eslogan, la descripción y el correo de contacto de la agencia en Ajustes, Agencia, y las viviendas destacadas de la página de inicio en Ajustes, Página de inicio.

Pasar a producción

Antes de que la agencia sea accesible desde internet:

  1. En el entorno de la API, NODE_ENV=production y un JWT_SECRET largo y aleatorio propio (Docker genera uno cuando no hay ninguno). En producción la API se niega a iniciar sin CORS_ORIGIN y dice qué valor falta.
  2. CORS_ORIGIN con el sitio web y el panel, FRONTEND_URL con el panel, PUBLIC_MEDIA_URL con la API seguida de /media.
  3. La base de datos y las subidas en almacenamiento persistente, con una copia de seguridad.
  4. La comprobación de estado del host en /api/health, y TRUST_PROXY=1 detrás de un proxy.
  5. Ambos frontends construidos con los valores públicos de NEXT_PUBLIC_*.
  6. En el sitio web, tu marca en src/config/brand.config.ts, y la política de privacidad en messages/privacy reescrita para tu agencia y tu país.
  7. Las contraseñas de la carga inicial cambiadas, o las cuentas de la carga inicial eliminadas.
  8. DEMO_MODE=false en la API y NEXT_PUBLIC_DEMO_MODE=false en ambos frontends, tal como se entrega.

No para una agencia con datos reales

yarn setup:fresh construye, elimina todas las tablas y carga los datos, cada vez que se ejecuta, y yarn db:reset elimina todas las tablas. Sirven para un entorno completamente nuevo, nunca como comando de inicio o de construcció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.