Saltar a contenido

Despliegue

Stack operativo

  • db: PostgreSQL 16 sin exposicion publica
  • api: backend ASP.NET Core 8 con volumen en /app/storage
  • tablet: frontend PWA servido por Nginx
  • docs: documentacion MkDocs servida por Nginx

URLs recomendadas

  • API: https://apifirma.jdmarquez.dev
  • tablet: https://tabletfirma.jdmarquez.dev/
  • docs: https://docsfirma.jdmarquez.dev/ (sugerida)
  • Swagger UI: https://apifirma.jdmarquez.dev/swagger
  • OpenAPI JSON: https://apifirma.jdmarquez.dev/swagger/v1/swagger.json

Variables del backend

  • BC_BEARER_TOKEN
  • DATABASE_URL o ConnectionStrings__Default
  • STORAGE_ROOT
  • MAX_PDF_MB
  • POLLING_LOCK_SECONDS
  • REQUEST_DEFAULT_EXPIRY_MINUTES
  • ACTIVATION_CODE_LENGTH
  • ACTIVATION_CODE_TTL_MINUTES
  • MAINTENANCE_INTERVAL_SECONDS
  • RETENTION_DAYS_ORIGINAL
  • RETENTION_DAYS_SIGNED
  • RETENTION_DAYS_AUDIT
  • ENABLE_HTTPS_ONLY
  • ALLOWED_ORIGINS

Variables publicas de la tablet

  • VITE_API_BASE_URL
  • VITE_DEFAULT_DEVICE_ID
  • VITE_POLLING_INTERVAL_MS

Desde ghcr.io/jdmarquezdev/bc-pdf-sign-tablet:0.1.2 estas variables se leen en runtime al arrancar el contenedor. No hace falta reconstruir la imagen para cambiar la URL de la API.

Instalacion con Coolify

Esta es la ruta de despliegue de referencia para el proyecto.

1. Preparar GHCR

Si las imagenes son privadas, configura un registry en Coolify para ghcr.io con:

  • usuario GitHub
  • PAT con read:packages
  • autorizacion SSO si la organizacion la exige

Imagenes publicadas:

  • API: ghcr.io/jdmarquezdev/bc-pdf-sign-api:0.1.2
  • tablet: ghcr.io/jdmarquezdev/bc-pdf-sign-tablet:0.1.2

2. Crear db

  • imagen postgres:16
  • sin exposicion publica
  • volumen persistente
  • base de datos, usuario y password dedicados

3. Crear api

  • tipo Docker Image o Dockerfile
  • puerto interno 8080
  • dominio HTTPS publico
  • volumen persistente montado en /app/storage
  • healthcheck por HTTP al path /health sobre el puerto interno 8080

Variables minimas sugeridas:

ASPNETCORE_ENVIRONMENT=Production
SWAGGER_ENABLED=true
DATABASE_URL=Host=db;Port=5432;Database=bc_pdf_sign;Username=bcpdfsign;Password=replace_me
BC_BEARER_TOKEN=replace_me
STORAGE_ROOT=/app/storage
ALLOWED_ORIGINS=https://tabletfirma.jdmarquez.dev
ENABLE_HTTPS_ONLY=true

4. Crear tablet

  • tipo Docker Image
  • imagen ghcr.io/jdmarquezdev/bc-pdf-sign-tablet:0.1.2
  • puerto interno 8080
  • dominio HTTPS publico
  • sin volumenes
  • healthcheck por HTTP al path / sobre el puerto interno 8080

Variables sugeridas:

VITE_API_BASE_URL=https://apifirma.jdmarquez.dev
VITE_DEFAULT_DEVICE_ID=
VITE_POLLING_INTERVAL_MS=4000

5. Crear docs

  • tipo Dockerfile
  • build context: raiz del repositorio
  • Dockerfile: docs.Dockerfile
  • puerto interno 8080
  • dominio HTTPS publico, por ejemplo https://docsfirma.jdmarquez.dev/
  • sin volumenes
  • sin variables obligatorias
  • healthcheck por HTTP al path / sobre el puerto interno 8080

La imagen genera el sitio con mkdocs build --strict y sirve el resultado estatico con Nginx.

6. Verificaciones iniciales

  1. Abrir https://apifirma.jdmarquez.dev/health
  2. Abrir https://apifirma.jdmarquez.dev/swagger
  3. Abrir https://tabletfirma.jdmarquez.dev/
  4. Si publicas documentacion, abrir https://docsfirma.jdmarquez.dev/
  5. Registrar una tablet y emitir codigo de activacion
  6. Activar la tablet desde la PWA

Instalacion sin Coolify

Esta ruta es un fallback manual para laboratorio, soporte o entornos donde no se use Coolify. La referencia principal del proyecto sigue siendo Coolify.

Opcion 1. Docker Compose en una VPS

El repositorio incluye compose.yaml para un entorno funcional local o de laboratorio.

docker compose up -d --build

Usa --build cuando quieras reconstruir las imagenes desde el codigo fuente. Si solo cambias variables runtime de la tablet en un entorno ya desplegado, no hace falta recompilar la imagen 0.1.2 o superior.

Servicios por defecto:

  • API en http://127.0.0.1:8080
  • tablet en http://127.0.0.1:3000
  • docs en http://127.0.0.1:8000
  • PostgreSQL en 127.0.0.1:5432

Notas:

  • En este modo la tablet usa VITE_API_BASE_URL=http://127.0.0.1:8080
  • ENABLE_HTTPS_ONLY va desactivado en local
  • para publicar en Internet, coloca un reverse proxy delante y cambia la URL publica de la tablet y de la API

Opcion 2. Contenedores sueltos con Docker

Ejemplo simplificado:

docker network create bc-pdf-sign

docker run -d --name db --network bc-pdf-sign \
  -e POSTGRES_DB=bc_pdf_sign \
  -e POSTGRES_USER=bcpdfsign \
  -e POSTGRES_PASSWORD=replace_me \
  -v bc-pdf-sign-pgdata:/var/lib/postgresql/data \
  postgres:16

docker run -d --name api --network bc-pdf-sign -p 8080:8080 \
  -e ASPNETCORE_ENVIRONMENT=Production \
  -e SWAGGER_ENABLED=true \
  -e DATABASE_URL="Host=db;Port=5432;Database=bc_pdf_sign;Username=bcpdfsign;Password=replace_me" \
  -e BC_BEARER_TOKEN=replace_me \
  -e STORAGE_ROOT=/app/storage \
  -e ALLOWED_ORIGINS=https://tabletfirma.jdmarquez.dev \
  -e ENABLE_HTTPS_ONLY=false \
  -v bc-pdf-sign-storage:/app/storage \
  ghcr.io/jdmarquezdev/bc-pdf-sign-api:0.1.2

docker run -d --name tablet --network bc-pdf-sign -p 3000:8080 \
  -e VITE_API_BASE_URL=https://apifirma.jdmarquez.dev \
  -e VITE_DEFAULT_DEVICE_ID=tablet-recepcion-1 \
  -e VITE_POLLING_INTERVAL_MS=4000 \
  ghcr.io/jdmarquezdev/bc-pdf-sign-tablet:0.1.2

docker build -t bc-pdf-sign-docs -f docs.Dockerfile .
docker run -d --name docs --network bc-pdf-sign -p 8000:8080 bc-pdf-sign-docs

Publicar la documentacion en Coolify

Configuracion recomendada

  • servicio nuevo: docs
  • fuente: Dockerfile del repositorio
  • build context: raiz del repo
  • Dockerfile path: docs.Dockerfile
  • puerto interno: 8080
  • dominio: https://docsfirma.jdmarquez.dev/ o el que decidas
  • healthcheck: HTTP, path /, puerto 8080

Pasos

  1. Crear servicio nuevo en Coolify.
  2. Seleccionar el mismo repositorio.
  3. Elegir docs.Dockerfile como Dockerfile.
  4. Configurar dominio publico para la documentacion.
  5. Desplegar.
  6. Verificar que carga la home y que la navegacion funciona.

Cuándo reconstruir

  • si cambias archivos en docs-mkdocs/, mkdocs.yml o dependencias, hace falta redeploy del servicio docs
  • si solo cambias api o tablet, la documentacion no necesita redeploy salvo que quieras reflejar esos cambios en el contenido

Problemas habituales de despliegue

GHCR devuelve unauthorized

Sintoma tipico:

error from registry: unauthorized

Revision recomendada:

  1. confirmar que el tag existe en GHCR
  2. comprobar si el paquete es publico o privado
  3. si es privado, usar PAT con read:packages
  4. autorizar SSO si aplica
  5. volver a probar con docker login ghcr.io y docker pull

La API intenta conectar a 127.0.0.1:5432

Sintoma tipico:

Failed to connect to 127.0.0.1:5432

Causa habitual:

  • DATABASE_URL mal configurado
  • uso de localhost dentro del contenedor

Solucion:

  • usar el hostname interno del servicio PostgreSQL, por ejemplo Host=db;Port=5432;...
  • no usar localhost en despliegue entre contenedores

El healthcheck de la tablet falla con errores SSL

Sintoma tipico:

ssl_client: SSL_connect
packet length too long

Causa habitual:

  • Coolify comprueba https://dominio:8080/ dentro del contenedor
  • la tablet sirve HTTP en el puerto interno 8080

Solucion:

  • configurar healthcheck interno por HTTP
  • path /
  • puerto 8080
  • no usar la URL publica HTTPS como check interno

La documentacion no abre en Coolify

Causas habituales:

  • se eligio mal el build context o el Dockerfile
  • el healthcheck usa HTTPS interno en vez de HTTP
  • faltan dependencias de MkDocs en la build

Solucion:

  • usar build context en la raiz del repo
  • usar docs.Dockerfile
  • configurar healthcheck HTTP sobre / y puerto 8080

La tablet sigue llamando a 127.0.0.1

Causa habitual:

  • imagen antigua construida con la URL local horneada

Solucion:

  • usar ghcr.io/jdmarquezdev/bc-pdf-sign-tablet:0.1.2 o superior
  • configurar VITE_API_BASE_URL en runtime en Coolify

CORS bloquea llamadas desde la tablet

Sintoma tipico:

  • errores en consola del navegador al llamar a la API

Solucion:

  • fijar ALLOWED_ORIGINS al dominio real de la tablet, por ejemplo https://tabletfirma.jdmarquez.dev

Swagger en despliegue

  • Swagger UI: https://apifirma.jdmarquez.dev/swagger
  • OpenAPI JSON: https://apifirma.jdmarquez.dev/swagger/v1/swagger.json
  • En produccion deja SWAGGER_ENABLED=true si quieres usarlo para soporte e integracion con BC.

Para mas detalle: