Configuración¶
Toda la configuración operativa del backend vive fuera del jar, en un application.yml junto
al ejecutable. Esta página documenta cada variable/clave real, de dónde sale y qué pasa si falta.
Para el detalle del proceso de arranque que la exige, ver
Backend → cómo arranca. Para el despliegue paso a paso, ver
Instalar en el servidor.
Config externa al jar y fail-fast¶
Decisión explícita del operador: "el yaml de configuración por completo tiene que estar fuera del
.jar, nada de sorpresas con yaml adentro del big fat jar". El jar empaquetado no contiene
ningún application*.yml/application*.properties — Spring Boot busca ./config/ relativo al
directorio de trabajo del proceso, sin ningún loader custom.
C:\work\sistemapremios\
├── sistemapremios-backend-0.0.1-SNAPSHOT.jar
├── config\
│ └── application.yml ← toda la config real vive acá
├── bases\
├── branding\
│ └── logo.png
└── logs\
El repo versiona backend/config/application.yml como referencia documentada — resuelve dev
y CI sin fricción (ambos corren con working directory backend/), y nunca contiene un valor
secreto: los ${SP_*} quedan sin resolver hasta que el entorno real los provee.
Sin config/application.yml, el proceso no arranca — a propósito
Un EnvironmentPostProcessor (ConfigExternaEnvironmentPostProcessor) corre antes que
cualquier bean y exige:
- La propiedad centinela
sp.config.externa: true— solo existe en el archivo externo, nunca embebida. Si falta, la excepción nombra el archivo esperado, el working directory real del proceso y sugiere--spring.config.additional-location=file:<ruta>/config/si no se puede controlar el working directory. - Dos claves de contrato del código, con su valor exacto:
spring.jackson.property-naming-strategy: SNAKE_CASE(si falta, toda la API cambia de formato y la landing/gestor rompen en silencio) yspring.jpa.hibernate.ddl-auto: validate(si falta, Hibernate podría alterar el esquema en vez de solo validarlo contra Flyway).
Nunca arranca con defaults embebidos. Mejor no arrancar que arrancar distinto a lo esperado. Detalle completo de la decisión en ADR-029.
AppDirectory / working directory es crítico en Windows Service
Spring busca ./config/ relativo al working directory del proceso, no a la ubicación del
jar. Con NSSM, esto significa que AppDirectory tiene que apuntar a la carpeta que contiene
config/ — un desajuste típico de "Start in" deja el servicio sin encontrar la config aunque
el jar esté en la ruta correcta.
Variables de entorno¶
| Variable | Default | Obligatoria | Para qué |
|---|---|---|---|
SP_DB_URL |
jdbc:sqlserver://localhost;databaseName=SistemaPremios;encrypt=false |
No | URL JDBC de SQL Server |
SP_DB_USER |
sa |
No | Usuario de la base |
SP_DB_PASSWORD |
— (fallback a SP_DB_PASS) |
Sí, en la práctica | Password de la base. SP_DB_PASS es el nombre viejo, obsoleto — sigue funcionando de fallback pero loguea un WARN |
SP_MASTER_KEY |
— | Sí | Base64 de 32 bytes (AES-256) para cifrar/descifrar el secreto HMAC de la clave de firma. Sin ella, el arranque falla con un mensaje explícito. Debe ser la misma clave usada al sembrar los datos, o los QR emitidos antes no vuelven a validar |
SP_GESTOR_USER |
admin |
No | Usuario de login del gestor |
SP_GESTOR_PASSWORD |
— (fallback a SP_GESTOR_PASS) |
Sí | Password del gestor. Sin ella, el arranque falla rápido — no hay camino de "arrancar igual y avisar" (la versión anterior generaba y logueaba una password aleatoria; eso viola la regla de secretos nunca en logs) |
SP_CLIENTE_NOMBRE |
Cliente |
No | Nombre del cliente mostrado en landing/gestor (branding multi-cliente) |
SP_CLIENTE_COLOR |
#E01020 |
No | Color primario de marca, formato #RRGGBB estricto — un valor inválido hace fallar el arranque |
SP_BRANDING_DIR |
./branding |
No | Carpeta donde vive logo.png del cliente |
SP_BASES_DIR |
— | No | Carpeta de las bases legales versionadas de la campaña (PDF subido desde el gestor) |
SP_MODO_PRUEBA |
false |
No | Habilita el generador de vouchers de prueba. Ver guarda de prod más abajo |
SP_BASE_URL |
http://localhost:8080 |
Sí, en producción | URL pública que se embebe dentro del contenido del QR. Si queda en localhost, los QR generados apuntan a localhost y no sirven fuera de esa máquina |
Las tres que muerden si las salteás
SP_GESTOR_PASSWORD (login del gestor — sin ella no arranca) · SP_BASE_URL (si queda en
localhost, los QR apuntan a localhost) · SP_MASTER_KEY (debe ser la misma que se usó al
sembrar los datos, o los QR no validan).
Claves de config (sp.*)¶
Estas viven en application.yml, no como variable de entorno directa (aunque casi todas se
resuelven a partir de las de arriba vía ${SP_*:default}):
| Clave | Default | Para qué |
|---|---|---|
sp.config.externa |
— | Centinela obligatorio, ver arriba. No borrar. |
sp.cliente.nombre |
${SP_CLIENTE_NOMBRE:Cliente} |
Branding |
sp.cliente.color-primario |
${SP_CLIENTE_COLOR:#E01020} |
Branding, validado #RRGGBB |
sp.branding.dir |
${SP_BRANDING_DIR:./branding} |
Carpeta del logo |
sp.modo-prueba.enabled |
${SP_MODO_PRUEBA:false} |
Ver Backend → modo prueba |
sp.base-url |
${SP_BASE_URL:http://localhost:8080} |
Base pública embebida en el QR |
sp.reconocimiento.habilitado |
true |
Perilla de privacidad por cliente para el reconocimiento de dispositivo — en false, la landing pide siempre el DNI |
sp.rate-limit.enabled |
true |
Ver Backend → rate limiting |
sp.rate-limit.limite |
30 |
Requests por ventana |
sp.rate-limit.ventana-ms |
60000 |
Tamaño de la ventana (ms) |
sp.rate-limit.cap-entradas |
10000 |
Tope de IPs trackeadas antes de purgar |
sp.seed.archivo |
— | Ver Backend → seed inicial. Sin esta property, SeedMinimo ni se registra como bean |
Cambiar un flag operativo no reempaqueta nada
Por ejemplo, apagar el reconocimiento de dispositivo para un cliente puntual es editar
sp.reconocimiento.habilitado: false en config/application.yml y reiniciar el servicio —
sin tocar código ni volver a buildear el jar. Es el objetivo completo de
ADR-029.
Perfiles¶
| Perfil | Uso |
|---|---|
(sin perfil) / dev, local |
Desarrollo. bootui (consola de desarrollo) se activa sola en AUTO; modo prueba puede estar prendido sin problema |
e2e |
Suite end-to-end (Playwright contra el jar empaquetado). Config propia en backend/config/application-e2e.properties |
load |
Pruebas de carga. Config propia en backend/config/application-load.properties |
prod |
Producción — ver guarda de abajo |
prod mata el modo prueba — no se pueden combinar
ModoPruebaConfig corre al arranque: si sp.modo-prueba.enabled=true y el perfil activo
contiene prod, el contexto no levanta. Es intencional — modo prueba nunca debe existir
en el ambiente real. La consecuencia práctica, documentada en el runbook de despliegue: si
necesitás generar QR de prueba en el servidor de producción real (para el smoke inicial),
corrés sin spring.profiles.active=prod — lo que también significa que bootui no queda
bloqueado por código en ese momento. La mitigación es de infraestructura: un reverse proxy
(Caddy) devuelve 404 en /bootui y /bootui/* de entrada, para que la consola de desarrollo
nunca quede expuesta públicamente aunque el proceso la tenga activa.
Ejemplo completo¶
Este es el config/application.yml real de un despliegue (basado en el runbook de instalación),
con los valores a completar marcados:
sp.config.externa: true # centinela ADR-029 — NO borrar
SP_DB_PASSWORD: "CAMBIAR"
SP_MASTER_KEY: "CAMBIAR" # base64 32 bytes — el MISMO usado al seed
SP_GESTOR_USER: "admin"
SP_GESTOR_PASSWORD: "CAMBIAR" # obligatoria: sin esto no arranca
SP_CLIENTE_NOMBRE: "Supermercados Caracol"
SP_CLIENTE_COLOR: "#e30613"
SP_BRANDING_DIR: "C:/work/sistemapremios/branding"
SP_MODO_PRUEBA: "true" # NO usar junto con perfil prod
SP_BASE_URL: "https://sistemapremios.tipre.com" # URL pública real, nunca localhost
management:
endpoints:
web:
exposure:
include: health
endpoint:
health:
show-details: when-authorized
server:
address: 127.0.0.1 # solo localhost — el reverse proxy es quien queda expuesto
port: 28880
forward-headers-strategy: framework
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
Este archivo no contiene secretos reales
El application.yml versionado en el repo (backend/config/application.yml) es la
referencia sin valores reales — los ${SP_*} quedan sin resolver. Los valores reales van en
la carpeta de deploy, fuera de git. Detalle del despliegue completo (NSSM, Caddy, TLS) en
Instalar en el servidor.