Saltar a contenido

Instalar en el servidor del cliente

Esta guía instala el Sistema de Premios como servicio de Windows en el servidor de destino: build del jar único, carpeta de deploy fuera del repo, config/application.yml con los valores reales del cliente, arranque a mano para verificar, y el servicio con NSSM para que quede corriendo solo y se levante con el sistema operativo.

No hace falta Docker: es un jar Java corriendo nativo en Windows, con SQL Server ya instalado en el mismo servidor o accesible por red.

Esta página deja la app corriendo en 127.0.0.1:28880, sin TLS

A propósito: acá dejamos la aplicación escuchando solo localhost. El paso de exponerla al público por HTTPS real es aparte — seguí con Publicar con HTTPS (Caddy + NSSM) inmediatamente después de terminar esta guía.

Prerrequisitos del servidor

  • JDK 21 instalado (el jar es bytecode Java 17, corre en cualquier JDK ≥17 — usamos 21 para estar alineados con el build).
  • SQL Server 2022 con la base de datos SistemaPremios ya creada (vacía; Flyway arma el esquema al primer arranque).
  • NSSM descargado en el servidor (para correr la app como servicio Windows).
  • Acceso de red del servidor a la instancia de SQL Server (local o remota).

1. Buildear el jar completo

El build se hace en tu máquina de build (o en el mismo servidor, si tiene Maven/Node). El perfil full empaqueta la landing y el gestor dentro del jar del backend — no hay que copiar nada de esos dos proyectos por separado.

cd C:\Work\Tipre\SistemaPremios\backend
mvn package -DskipTests -Pfull

Esto genera:

backend\target\sistemapremios-backend-0.0.1-SNAPSHOT.jar

con la landing (/) y el gestor (/gestor/) ya adentro.

2. Crear la carpeta de deploy (fuera del repo)

La carpeta de deploy es donde vive todo lo operativo del servidor — el jar, la config real con secretos, las bases legales, el branding y los logs. No es un checkout de git: nunca se versiona.

mkdir C:\work\sistemapremios
mkdir C:\work\sistemapremios\config
mkdir C:\work\sistemapremios\bases
mkdir C:\work\sistemapremios\branding
mkdir C:\work\sistemapremios\logs

Copiá el jar recién buildeado y el logo del cliente:

copy backend\target\sistemapremios-backend-0.0.1-SNAPSHOT.jar C:\work\sistemapremios\
copy docs\branding\caracol\logo.png C:\work\sistemapremios\branding\logo.png

3. Escribir config\application.yml

Este es el archivo que reemplaza al que viaja en el repo como referencia (ver ADR-029 y el detalle de cada clave en Configuración). Va junto al jar, en C:\work\sistemapremios\config\application.yml, y acá sí lleva los valores reales.

Creá el archivo con este contenido, reemplazando cada CAMBIAR:

# config externa (ADR-029). Va junto al jar. NO en git (valores reales).

sp.config.externa: true          # centinela ADR-029 — NO borrar

# ── valores del cliente (resuelven los ${SP_*} de abajo) ──
SP_DB_PASSWORD: "CAMBIAR"                              # sa de SQL Server (SistemaPremios)
SP_MASTER_KEY: "CAMBIAR"                               # base64 32 bytes — EL MISMO usado al seed
SP_GESTOR_USER: "admin"                                # login del gestor
SP_GESTOR_PASSWORD: "CAMBIAR"                           # login del gestor (obligatorio: sin esto NO arranca)
SP_CLIENTE_NOMBRE: "Supermercados Caracol"
SP_CLIENTE_COLOR: "#e30613"
SP_BRANDING_DIR: "C:/work/sistemapremios/branding"     # con logo.png adentro
SP_MODO_PRUEBA: "true"                                  # generador de QR de prueba (NO usar perfil prod)
SP_BASE_URL: "https://sistemapremios.tipre.com"        # URL pública que va DENTRO del QR (¡no localhost!)

management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      show-details: when-authorized

server:
  address: 127.0.0.1                     # solo localhost — solo el reverse proxy entra
  port: 28880
  forward-headers-strategy: framework    # detrás de Caddy ya reescribe la IP real (X-Forwarded-For) — NO cambiar
  tomcat:
    allow-trace: false
  compression:
    enabled: true
    mime-types: text/html,text/css,application/javascript,text/javascript,application/json
    min-response-size: 1024

spring:
  application:
    name: sistemapremios-backend
  datasource:
    url: ${SP_DB_URL:jdbc:sqlserver://localhost;databaseName=SistemaPremios;encrypt=false}
    username: ${SP_DB_USER:sa}
    password: ${SP_DB_PASSWORD:${SP_DB_PASS:}}
  jpa:
    hibernate:
      ddl-auto: validate
    open-in-view: false
    properties:
      hibernate:
        jdbc:
          time_zone: America/Argentina/Buenos_Aires
        query:
          in_clause_parameter_padding: true
  flyway:
    enabled: true
  jackson:
    property-naming-strategy: SNAKE_CASE
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

sp:
  cliente:
    nombre: ${SP_CLIENTE_NOMBRE:Cliente}
    color-primario: ${SP_CLIENTE_COLOR:#E01020}
  branding:
    dir: ${SP_BRANDING_DIR:./branding}
  modo-prueba:
    enabled: ${SP_MODO_PRUEBA:false}
  base-url: ${SP_BASE_URL:http://localhost:8080}
  reconocimiento:
    habilitado: true

Tres variables que muerden si las salteás

  • SP_GESTOR_PASSWORD — sin ella el backend no arranca. No hay fallback silencioso.
  • SP_BASE_URL — si queda en localhost, los QR que genera el sistema apuntan a localhost y ningún cliente fuera de esa máquina puede escanearlos.
  • SP_MASTER_KEY — tiene que ser la misma que se usó al sembrar los datos (seed), o los QR emitidos antes no vuelven a validar.

Fallback LAN sin reverse proxy (self-signed, no recomendado para producción pública)

Si por algún motivo no vas a poner Caddy delante (por ejemplo, una prueba interna en la LAN del cliente sin dominio público), podés reemplazar el bloque server de arriba por:

server:
  port: 8443
  ssl:
    enabled: true
    key-store: "file:C:/work/sistemapremios/sp-dev.p12"
    key-store-password: changeit
    key-store-type: PKCS12
    key-alias: sp

Con Caddy delante (el camino recomendado, ver el paso siguiente) esto no hace falta.

4. Probar el arranque a mano

Antes de instalarlo como servicio, corré el jar directamente para confirmar que todo está en orden. Parado en la carpeta de deploy:

cd C:\work\sistemapremios
& "C:\Program Files\Java\jdk-21\bin\java.exe" -jar sistemapremios-backend-0.0.1-SNAPSHOT.jar

Flyway migra la base al arrancar. Si falta la carpeta config\, o si le falta alguna clave de contrato, el fail-fast de ADR-029 corta el arranque y te dice exactamente qué archivo esperaba y en qué working directory buscó — nunca arranca en silencio con defaults.

En otra terminal, verificá el health check:

curl.exe http://127.0.0.1:28880/api/salud

Debería responder {"estado":"ok","base_datos":"ok"}. Si respondió bien, cortá el proceso (Ctrl+C) y pasá al servicio.

5. Instalar el servicio con NSSM

nssm install SistemaPremios "C:\Program Files\Java\jdk-21\bin\java.exe" "-jar C:\work\sistemapremios\sistemapremios-backend-0.0.1-SNAPSHOT.jar"
nssm set SistemaPremios AppDirectory C:\work\sistemapremios
nssm set SistemaPremios AppStdout C:\work\sistemapremios\logs\out.log
nssm set SistemaPremios AppStderr C:\work\sistemapremios\logs\err.log
nssm set SistemaPremios Start SERVICE_AUTO_START
nssm start SistemaPremios

AppDirectory es CRÍTICO — no es un detalle cosmético

Spring Boot busca ./config/ relativo al working directory del proceso, no a la ubicación del jar. Si AppDirectory no apunta a C:\work\sistemapremios (la carpeta que contiene config\), el servicio arranca con el proceso corriendo en otro directorio y el chequeo de config externa falla — aunque el jar esté en la ruta correcta. Es el error más común al migrar de "corrí bien a mano" a "no arranca como servicio".

Confirmá que el servicio está arriba:

nssm status SistemaPremios
curl.exe http://127.0.0.1:28880/api/salud

6. Backup diario

La carpeta de deploy y la base de datos son lo único que no se recupera con un simple re-deploy del jar (el jar se regenera desde el repo; los datos, no). Como mínimo, programá dos backups diarios fuera de horario pico:

Backup de la base de datos (ejemplo con sqlcmd, ajustá credenciales y ruta):

sqlcmd -S localhost -U sa -P "CAMBIAR" -Q "BACKUP DATABASE SistemaPremios TO DISK = 'C:\backups\SistemaPremios_$(Get-Date -Format yyyyMMdd).bak'"

Backup de la carpeta de deploy (config, branding y logs — no hace falta backupear el jar, ese sale del repo):

robocopy C:\work\sistemapremios\config C:\backups\sistemapremios\config /MIR
robocopy C:\work\sistemapremios\branding C:\backups\sistemapremios\branding /MIR

Programalo con el Programador de tareas de Windows

Envolvé estos comandos en un .ps1 y agendalo con schtasks o el Programador de tareas de Windows, corriendo una vez por día fuera del horario de mayor tráfico de la campaña. C:\backups\ es un ejemplo — usá la ruta de backup que ya tenga definida la infraestructura del cliente (idealmente en otro disco o servidor).

Siguiente paso

La app ya corre como servicio, pero solo responde en 127.0.0.1:28880 — todavía no es accesible desde afuera. Para publicarla con HTTPS real (necesario para que el escáner de DNI de la landing funcione en cualquier celular), seguí con Publicar con HTTPS (Caddy + NSSM).