Saltar a contenido

Desplegar API, web y documentación en Coolify

Esta guía publica todo el check-in: activa el módulo en la API compartida de firmas, despliega la web de huéspedes y crea su portal documental independiente. Business Central requiere además su propia instalación/configuración, al final del recorrido. La guía de documentación detalla únicamente el tercer recurso.

Tres recursos, tres configuraciones

Usa el mismo repositorio bc-pdf-sign y una revisión remota que contenga backend/, checkin-web/, docs-checkin/ y los archivos de build. Las aplicaciones pueden estar en proyectos/entornos distintos de Coolify: la web accede a la URL pública de la API. Conserva el recurso API, su PostgreSQL y su almacenamiento existentes:

Ajuste API compartida Web de huéspedes Documentación check-in
Recurso Coolify Actualizar el de firmas existente Crear aplicación propia Crear aplicación propia
Repositorio/rama bc-pdf-sign, revisión aprobada Mismo repositorio y revisión Mismo repositorio y revisión
Base Directory /backend /checkin-web /
Build pack / strategy Dockerfile desde Git; o imagen verificada si ya se opera así Railpack + salida estática Dockerfile desde Git
Dockerfile / salida Dockerfile, relativo a la base Publish Directory /dist, dentro de la base docs-checkin.Dockerfile, relativo a raíz
Install / Build Los define el Dockerfile npm ci --include=dev / npm run build Los define el Dockerfile; MkDocs strict
Puerto interno 8080 80, Nginx generado 8080
Dominio de ejemplo https://api.example.com https://checkin.example.com https://docs-checkin.example.com
Variables build Ninguna nueva para check-in VITE_API_BASE_URL, RAILPACK_NODE_VERSION Ninguna
Variables runtime Conexión/secreto/opciones CHECKIN_* y configuración existente Ninguna necesaria para el JavaScript estático Ninguna
Persistencia PostgreSQL privado + volumen /app/storage existente Sin volumen Sin volumen
Healthcheck interno HTTP /health en 8080, incluido en imagen HTTP / en 80 HTTP / en 8080, incluido en imagen

Los dominios son ejemplos. Conserva los reales de recursos existentes y configura DNS/HTTPS para los nuevos. El puerto del dominio apunta al contenedor; el visitante entra por HTTPS estándar, no por el puerto interno. Dominios en Coolify.

Antes de desplegar

  1. Verifica que la rama remota contiene los archivos; cambios solo locales no llegan a Coolify. Para repositorios privados, prepara su conexión Git autorizada.
  2. Identifica el recurso API existente, su PostgreSQL y su volumen. Haz backup y ensaya las migraciones en una copia antes de activar el módulo.
  3. Elige los dominios de web y documentación y configura DNS al servidor correspondiente. Ambos sirven desde la raíz del dominio.
  4. Sigue el orden API → web → documentación → BC → comprobación completa.

compose.yaml no incluye la web de huéspedes ni transmite las variables CHECKIN_*. El workflow de tags publica API y tablet de firmas, no la web de huéspedes ni el portal documental. No presupongas que un tag antiguo de API contiene check-in. La receta siguiente no acredita despliegue ni imagen publicada.

API en Coolify

Actualiza el recurso API compartido que ya usan las firmas: conserva dominio, conexión PostgreSQL, volumen /app/storage y sus parámetros operativos. No crees una segunda API con otra base para activar check-in. Si es una instalación nueva, prepara primero PostgreSQL privado y el volumen persistente; después crea una única API compartida. Revisa migraciones y backup antes de activarlo.

  1. Selecciona una revisión de fuentes que incluya backend/src/Api/Features/CheckIn/. Si construyes desde Git, usa Base Directory /backend y Dockerfile Location Dockerfile (relativa a esa base). Como alternativa usa una imagen inmutable cuya publicación y contenido hayas verificado; esta guía no asigna un tag de release de check-in.
  2. Conserva conexión PostgreSQL, bearer de firmas, volumen y dominios existentes. Añade CHECKIN_ENABLED=true, sitios, zona horaria y secreto administrativo. Mantén CHECKIN_BC_ENABLED=false y rutas [] durante la primera comprobación. Introduce estas variables como runtime, con secretos no disponibles durante build; consulta la tabla completa.
  3. Configura CORS con el origen exacto de la web si se sirve en otro dominio. Termina TLS en el proxy y limita el acceso directo a la API; la configuración actual del host acepta cabeceras reenviadas sin lista restrictiva de proxies.
  4. Guarda configuración y redespliega la API. Revisa migraciones/log de arranque y salud. El Dockerfile ya incluye GET http://127.0.0.1:8080/health; Coolify utiliza ese healthcheck de imagen. El proxy termina HTTPS, el contenedor escucha HTTP.
  5. Prueba la ruta de recepción y un alta ficticia. /health confirma base y storage del host, no entrega a BC ni la totalidad del módulo.

No desactives la verificación TLS ni expongas PostgreSQL públicamente. En varias réplicas, añade limitación de peticiones en el proxy o distribuida: los 60/minuto actuales son por proceso e IP.

Publicar la web estática

Crea una aplicación desde Git para la web en el proyecto/entorno elegido, aunque la API siga en otro proyecto. Para un repositorio privado, selecciona la GitHub App autorizada o una deploy key con acceso de lectura. Selecciona el repositorio y revisión aprobados, Railpack como Build pack y Base Directory /checkin-web. Esta carpeta contiene package.json y package-lock.json; la raíz del repositorio no contiene el manifiesto Node y no es la base de esta aplicación.

En Output type selecciona Static site; después de crear la aplicación, el ajuste puede aparecer como Site type Static. Usa Publish Directory /dist, relativo a la base, y puerto interno 80. En esta modalidad Coolify copia la salida a Nginx; no copies el puerto de Caddy de ejemplos de Railway. Railpack está en Beta en Coolify y requiere Docker Buildx tanto en el servidor de build como en el helper. Guía oficial de Railpack en Coolify.

Revisa los comandos detectados: instalación npm ci --include=dev, para disponer de TypeScript y Vite durante build, y build npm run build. Deja Start Command vacío. No fijes npm run dev ni npm run preview como servidor de producción. No necesitas un Dockerfile web ni un archivo railpack.json para este recorrido. Nixpacks está en mantenimiento y esta guía usa su sucesor Railpack para nuevas aplicaciones. Estado de Nixpacks.

En Environment Variables, configura estos valores como disponibles durante la build:

RAILPACK_NODE_VERSION=24
VITE_API_BASE_URL=https://api.example.com

Sustituye la URL por la API pública HTTPS real, sin /v1 final. El navegador del huésped debe poder acceder a ella. RAILPACK_NODE_VERSION selecciona Node para el builder; no es una variable de la aplicación. Retira el antiguo ajuste de versión de Nixpacks. Confirma en el log que se detecta Node y se instala npm; si aparece npm: not found, revisa primero que Base Directory sea /checkin-web y que el plan detecte su package.json. Detección y versiones Node en Railpack.

VITE_API_BASE_URL queda incrustada en el JavaScript. Cambiarla exige nueva build, no un simple restart. No copies el mecanismo runtime-config.js de la tablet: esta web no lo implementa. Los secretos administrativos/BC pertenecen solo al backend, nunca a variables Vite. Coolify separa los alcances de build y runtime. Variables y alcance.

En la API añade el origen exacto de la web a ALLOWED_ORIGINS, conservando el origen de la tablet. Configura el dominio HTTPS de la web apuntando al puerto interno 80, sin prefijo de ruta. Añade healthcheck HTTP GET / en 80 en el recurso estático y comprueba que la imagen dispone de curl o wget. Healthchecks de Coolify.

Antes de publicar datos reales, configura Cache-Control: no-store para index.html en la configuración Nginx del sitio y comprueba la cabecera; los assets con hash pueden usar caché larga. Coolify permite Custom Nginx configuration para estas reglas; guardarlas requiere reconstruir la imagen estática. No se afirma que el valor predeterminado ya tenga esa política. La web usa / con query/fragmento, no rutas anidadas: no necesita un fallback de router; sus recursos presuponen la raíz del dominio.

Pulsa Deploy, revisa build y runtime logs y abre https://checkin.example.com/?site=las-torres&mode=reception con tu dominio real. Comprueba que la petición a /v1/checkin/sites/las-torres/reception llega a la API y devuelve JSON, no HTML. Prueba también una invitación provisionada.

El recorrido anterior usa dominios separados para hacer explícita la conexión y CORS. Solo deja la URL Vite vacía si has configurado un proxy de producción que envíe /v1 a la API, preservando esa ruta. El proxy de Vite pertenece al desarrollo; no configura Coolify. Evita registros de cuerpos/formularios o tokens en proxy/API.

Publicar el portal documental

Crea un tercer recurso Git/Dockerfile con Base Directory /, docs-checkin.Dockerfile, puerto 8080 y su dominio HTTPS. No tiene variables ni persistencia de huéspedes. El Dockerfile ejecuta MkDocs strict y sirve solo la documentación de check-in.

Sigue Publicar solo la documentación para los campos del panel, healthcheck, Deploy y recuperación. Verifica portada, navegación, búsqueda y assets. Publicar este recurso no despliega los otros dos ni sustituye sus comprobaciones.

Activar la entrega a BC

  1. Completa el receptor, permisos, Entra y adapter en un sandbox.
  2. Añade al backend CHECKIN_BC_ROUTES_JSON con el destino validado y habilita CHECKIN_BC_ENABLED=true. Una configuración inválida puede impedir el arranque del host compartido: compruébala antes del cambio de producción.
  3. Redespliega y observa una entrega ficticia por su recibo, primero inbox_received y después imported tras la acción del operador.
  4. Revisa el histórico held y libera únicamente los recibos aprobados. Las nuevas entradas pending acumuladas con BC apagado empiezan a enviarse al activar una ruta válida.

Permite salida HTTPS del backend a login.microsoftonline.com y api.businesscentral.dynamics.com. Nunca copies client secret o token administrativo a Vite, QR, capturas o documentación pública.

Comprobación antes de apertura

Verifica con datos sintéticos recepción, reserva con dos plazas, registro y reintento idéntico, documento duplicado, última plaza, invitación caducada y sitio incorrecto. En la web comprueba siete idiomas, móvil, teléfono, menor de 14, bloqueo durante resultado incierto y recibo. En BC confirma la persona y su estancia, no solo el HTTP de inserción.

Confirma también continuidad de las firmas existentes, backups/restauración en otro entorno, privacidad y retención, revisión de traducciones y soporte de recepción. Las pruebas de navegador con API simulada no acreditan la concurrencia PostgreSQL ni la importación BC real. El runbook detalla incidencias y retirada segura.

Comprueba también la navegación y búsqueda del portal documental. Para actualizar, reconstruye el recurso cuyas fuentes cambiaron: una nueva URL Vite requiere rebuild de web; variables backend requieren recrear su contenedor. Para volver atrás usa el runbook de API/web o el rollback de documentación, según el recurso.

Referencias de configuración y laboratorio

Los apartados siguientes amplían las variables y migraciones del recorrido Coolify; la prueba local queda como anexo. Los nombres del panel se comprobaron con la documentación oficial el 25 de octubre de 2026 y pueden variar por versión.

Configuración del backend

.env.example es la referencia de variables del repositorio. Configura valores reales en el proceso o en los secretos del recurso API. No pongas secretos en archivos públicos de la web ni de este portal.

Variable Valor inicial / uso
CHECKIN_ENABLED false; activa rutas, DbContext y migraciones
CHECKIN_SITE_SLUGS las-torres; lista de sitios separados por comas, con distinción de mayúsculas
CHECKIN_TIME_ZONE Europe/Madrid; fecha de negocio común a los sitios de esta instalación
CHECKIN_ADMIN_TOKEN Vacío; establece un secreto aleatorio independiente de al menos 32 caracteres
CHECKIN_BC_ENABLED false; activa el worker de entrega
CHECKIN_BC_ROUTES_JSON []; rutas y credenciales Entra por sitio, exclusivamente en backend
DATABASE_URL Conexión runtime existente, formato Npgsql o URI PostgreSQL
ConnectionStrings__Default Alternativa si no existe DATABASE_URL
ALLOWED_ORIGINS Orígenes públicos autorizados, separados por comas y sin ruta; conserva el de la tablet
ENABLE_HTTPS_ONLY true en servidor con proxy configurado; false solo en laboratorio HTTP
ASPNETCORE_ENVIRONMENT Production en servidor
SWAGGER_ENABLED Controla la publicación de /swagger
BC_BEARER_TOKEN Credencial existente de firmas; el host sigue usando su configuración habitual
STORAGE_ROOT Volumen de PDFs existente, normalmente /app/storage; lo comprueba /health

La nueva funcionalidad no introduce cambios en los parámetros de firma/retención de PDFs. Mantén sus valores operativos del entorno. El host añade algunos orígenes CORS existentes de tablet/local además de ALLOWED_ORIGINS; no interpretes esa variable como eliminación de esos orígenes. CORS no sustituye autenticación ni protección de red.

Estas variables son solo herramientas, no configuración del servidor publicado:

Variable Uso
CHECKIN_DESIGN_DATABASE_URL EF CLI, formato Npgsql; independiente de DATABASE_URL
CHECKIN_TEST_DATABASE_URL Pruebas PostgreSQL; base dedicada cuyo nombre termina en _checkin_tests
CHECKIN_WEB_TEST_URL Proceso de pruebas de navegador de la web, no variable Vite ni runtime

Migraciones y persistencia

Con el módulo activado, el arranque aplica las migraciones de CheckInDbContext. Usa la misma conexión PostgreSQL que firmas, pero tablas checkin.reservations, checkin.submissions, checkin.deliveries e historial checkin.__EFMigrationsHistory. Las migraciones de AppDbContext siguen teniendo su ciclo separado.

Antes de activar en una base existente, realiza backup y ensaya la actualización en una copia. Coordina un arranque de migración controlado antes de ampliar réplicas. La migración de outbox deja registros históricos en held para revisión y liberación explícita; no exporta el histórico automáticamente.

Para inspección con una instalación de dotnet-ef compatible con EF Core 8:

$env:CHECKIN_DESIGN_DATABASE_URL = 'Host=127.0.0.1;Port=5432;Database=checkin_design;Username=postgres;Password=<password>'
dotnet ef migrations list --context CheckInDbContext --project backend/src/Api --startup-project backend/src/Api
dotnet ef migrations script --idempotent --context CheckInDbContext --project backend/src/Api --startup-project backend/src/Api --output checkin-migrations.sql

El script es para revisión y ejecución controlada en el destino correcto. La factory de diseño no inicia el host PDF; si no defines su variable usa la base local checkin_design, no la conexión runtime. No uses EnsureCreated, borrado del esquema, eliminación de volúmenes ni downgrade automático para activar o retirar este módulo.

Prueba local

Este anexo es opcional para laboratorio; el recorrido principal de esta página es Coolify. Necesitas .NET 8 SDK, PostgreSQL accesible y Node 22.12+ con npm. Usa una base de laboratorio, no la de producción. Las fuentes actuales de la web se han usado con Node 24.18; respeta el lockfile.

Si usas el PostgreSQL de Compose, arranca solo ese servicio desde la raíz del repositorio:

docker compose up -d db

Ese servicio crea bc_pdf_sign con postgres/postgres y expone 5432: son valores de laboratorio. Si ya tienes PostgreSQL, crea una base/usuario de prueba y sustituye la conexión siguiente. No arranques otro proceso API en un puerto ya ocupado.

En PowerShell, desde bc-pdf-sign, establece las variables del proceso API:

$env:ASPNETCORE_ENVIRONMENT = 'Development'
$env:DATABASE_URL = 'Host=127.0.0.1;Port=5432;Database=bc_pdf_sign;Username=postgres;Password=postgres'
$env:BC_BEARER_TOKEN = 'local-signing-only-replace-me'
$env:STORAGE_ROOT = Join-Path $PWD 'storage'
$env:ENABLE_HTTPS_ONLY = 'false'
$env:SWAGGER_ENABLED = 'true'
$env:CHECKIN_ENABLED = 'true'
$env:CHECKIN_SITE_SLUGS = 'las-torres'
$env:CHECKIN_TIME_ZONE = 'Europe/Madrid'
$env:CHECKIN_ADMIN_TOKEN = [guid]::NewGuid().ToString('N') + [guid]::NewGuid().ToString('N')
$env:CHECKIN_BC_ENABLED = 'false'
$env:CHECKIN_BC_ROUTES_JSON = '[]'
$env:ALLOWED_ORIGINS = 'http://127.0.0.1:5174,http://localhost:5174'
dotnet run --project backend/src/Api/Api.csproj --no-launch-profile --urls http://127.0.0.1:8080

Conserva el secreto administrativo generado en un lugar seguro si vas a provisionar desde otra terminal; ambas deben usar el mismo valor. Copiar .env.example no carga variables en ASP.NET ni en el bloque environment de Compose.

En otra terminal, desde la raíz de bc-pdf-sign:

Set-Location checkin-web
npm ci
$env:VITE_API_BASE_URL = ''
npm run dev -- --port 5174 --strictPort

Abre http://127.0.0.1:5174/?site=las-torres&mode=reception. Con URL base vacía, el proxy de desarrollo de Vite envía /v1 a http://127.0.0.1:8080. Se fija 5174 expresamente para no competir con la tablet de firmas; Vite no tiene ese puerto fijado en sus fuentes.

Comprueba /health, /swagger y /v1/checkin/sites/las-torres/reception en la API. Sigue el ejemplo de provisión y registro para probar también una invitación. Las nuevas entregas quedan pending mientras BC esté desactivado; es el comportamiento previsto.