Version: 1.0
Fecha: 23 de Mayo, 2026
Estado: NORMATIVO - Patrones operativos del upgrade
Arquitecto: Carlos Alberto Torres Camargo
Documento operativo con los patrones, convenciones y procedimientos que aplican al deploy y operacion del stack post stack-2026-05-23. Sirve como referencia rapida para el equipo de plataforma cuando ajuste el compose, agregue un servicio, modifique credenciales o active una feature multitenant.
.env por Grupo de ComposeCada grupo de compose en nodo-01 tiene su propio .env con todas las variables per-profile + secretos. El docker-compose.yml referencia esas variables via env_file:.
~/docker/compose/
business/server/.env
business/server/docker-compose.yml
business/business/.env
business/business/docker-compose.yml
nebula/cross-cutting/.env
nebula/cross-cutting/docker-compose.yml
nebula/business-domains/finance/.env
nebula/business-domains/finance/docker-compose.yml
# Profile + ambiente
APP_PROFILE=dev
SPRING_PROFILES_ACTIVE=common,dev
CONFIG_ENV=dev-config
EUREKA_SERVICE_URL=http://simappe-eureka-server:8761
# Spring runtime
SPRING_MAIN_LAZY_INITIALIZATION=true
SPRING_THREADS_VIRTUAL_ENABLED=true
# Git config repo del cliente (lo lee simappe-config-server)
CONFIG_GIT_URI=https://gitlab.centricasoluciones.com/simappe/config/simappeconfig.git
CONFIG_GIT_USERNAME=arquitecto.centrica
CONFIG_GIT_PASSWORD=<glpat-... viva en gestor de secretos, no en repo>
# Encryption key (AES-256 base64). Generar con: openssl rand -base64 32
DB_ENCRYPTION_KEY=<32 bytes base64; backupear fuera de repo>
| Grupo | Var extra | Razon |
|---|---|---|
nebula/cross-cutting |
TZ=America/Bogota |
Timezone del container Nebula |
nebula/cross-cutting |
DATABASE_TEMPLATE_NO_SQL=mongodb://sysadmin:centrica2026@mongodb-dev:27017/simappe_template_structure?authSource=admin |
Workaround para bug en MongoConfiguration.java:19 que cae a default hardcoded si no se inyecta. |
docker-compose.yml minimalistaEl compose ya no contiene environment hardcoded. Solo:
services:
simappe-config-server:
image: 10.110.0.2:5000/simappe/simappe-config-server:latest
container_name: simappe-config-server
env_file:
- .env
ports:
- "8890:8890"
networks:
- dev-network
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost:8890/actuator/health || exit 1"]
...
Beneficios:
.env) para cambiar credenciales o profile.docker-compose.yml es generico y se puede versionar en Git si se desea..env sin rebuild de imagen.SPRING_PROFILES_ACTIVE=common,<profile>Spring Cloud Config Server lee del Git repo del cliente y sirve los archivos cuyo nombre coincide con los perfiles activos del cliente:
application.yml (default, siempre)application-<profile>.yml (por cada profile activo)<servicio>.yml<servicio>-<profile>.yml (por cada profile activo)El archivo application-common.yml se carga solo si common esta entre los perfiles activos. Si el cliente arranca con SPRING_PROFILES_ACTIVE=dev solamente, application-common.yml queda huerfano (no se carga).
Las propiedades nuevas del upgrade (application.security.db-encryption-key, spring.main.lazy-initialization, etc.) viven en application-common.yml. Sin common activo, el codigo nuevo no recibe esas propiedades y se comporta segun los defaults internos del JAR (que pueden no ser los deseados).
Todos los servicios del stack deben arrancar con SPRING_PROFILES_ACTIVE=common,<ambiente> donde <ambiente> es dev, local, localhost, qa o prod.
Implementacion: variable en el .env del compose:
SPRING_PROFILES_ACTIVE=common,dev
En
nodo-01(DEV de Centrica):common,devaplica a los 4 grupos de compose.
# Asegurarse de que infra externa (Postgres, Mongo, Redis, Kafka, Oracle, Minio) este UP
docker ps | grep -E "postgres-dev|mongodb-dev|redis-dev|kafka-dev|oracle-xe|minio-dev"
# Grupo server (config + eureka + oauth2 + gateway + monitor-logs)
cd ~/docker/compose/business/server && docker compose up -d
# Grupo business (admin + client) — depende de los anteriores
cd ~/docker/compose/business/business && docker compose up -d
# Nebula cross-cutting (masters)
cd ~/docker/compose/nebula/cross-cutting && docker compose up -d
# Nebula finance domain (accounting-core)
cd ~/docker/compose/nebula/business-domains/finance && docker compose up -d
Cada servicio tiene healthcheck con start_period: 300s para tolerar el arranque inicial. La salud se chequea con wget -q --spider http://localhost:<port>/actuator/health (servicios HTTP) o pgrep -f java (servicios sin endpoint accesible facilmente).
| Paso | Property a true |
Despues de activar... |
|---|---|---|
| 1 | simappe.multitenant.tenant-resolver.enabled |
Validar logs: cada request resuelve TenantContext desde el JWT. Metrica simappe_tenant_context_missing_total cerca de 0. |
| 2 | simappe.multitenant.audit.enabled |
Eventos en topic user-events incluyen tenant fields. |
| 3 | simappe.multitenant.query-filter.enabled |
Queries Hibernate aplican WHERE tenant. Revisar endpoints cross-tenant (dashboards admin, jobs). |
| 4 | simappe.multitenant.kafka.enabled |
Headers tenant viajan en producers y consumers. |
| 5 | simappe.multitenant.mongo.enabled |
Solo despues de configurar database_config_v2 con Mongo per-tenant. Sin esa infra, el servicio falla. |
simappeconfig/dev-config/simappe-<servicio>-dev.yml (o application-common.yml para propiedades cross-servicio).feature/activate-<feature>-<fecha> + MR a main del simappeconfig (recordar: este repo es excepcion, va a main no develop).POST http://localhost:8890/actuator/refresh (o equivalente) en cada servicio afectado para recoger la nueva config sin reiniciar.${VAR:} en application-*.yml..env del compose del cliente o en gestor de secretos externo..env esta en .gitignore (verificar) y se respalda fuera del repo.| Secreto | Frecuencia | Procedimiento |
|---|---|---|
CONFIG_GIT_PASSWORD (PAT GitLab) |
Cada renovacion del PAT (anual o segun politica) | Actualizar .env + restart simappe-config-server. Otros servicios no lo usan. |
DB_ENCRYPTION_KEY |
NUNCA, salvo incidente de seguridad | Si se rota: re-cifrar todos los rows con prefijo enc:v1: antes del switch (ejecutar LegacyPasswordEncryptionMigration con la key vieja + plaintext + nueva key). Operacion delicada, planificar como migracion. |
| Passwords de DBs (Postgres, Oracle, Mongo) | Segun politica del cliente | Actualizar en .env (si aplica) y en simappeconfig (si esta servido por config-server). Restart servicios. |
| Tokens de proveedores (MailerSend, AWS SES) | Segun politica del proveedor | Actualizar en simappeconfig/dev-config/simappe-admin-dev.yml o .env. Refresh config-server. |
openssl rand -base64 32
Resultado: 32 bytes random codificados en base64. Pegar en .env:
DB_ENCRYPTION_KEY=<output del comando>
Backupear el valor en gestor de secretos del cliente (vault, password manager, etc.) antes del primer arranque.
Cuando el licenciante entrega un nuevo release y se quiere deployar uno o varios servicios actualizados:
10.110.0.2:5000/simappe/<servicio>:<tag>).cd ~/docker/compose/business/server
docker compose pull <servicio>
docker compose up -d --force-recreate <servicio>
docker ps | grep <servicio> debe mostrar (healthy)).docker logs --since 5m <servicio> 2>&1 | grep -iE "ERROR|FATAL|Caused by"
Nota critica:
docker compose up -d --force-recreateNO hace pull automatico de la imagen. Si la imagen:latestcambio en el registry, ejecutar explicitamentedocker compose pull <servicio>antes delup. Esta es la diferencia con el comandodocker compose up -d --build.
Cuando se modifica el repo simappeconfig (PR a main mergeado):
# Opcion 1: refresh a un servicio especifico
curl -X POST http://localhost:8890/actuator/refresh # config-server primero
curl -X POST http://localhost:<puerto-servicio>/actuator/refresh
# Opcion 2: restart del servicio (mas seguro, mas costoso)
cd ~/docker/compose/<grupo>
docker compose restart <servicio>
El config-server usa
force-pull: trueen su config Git, por lo que cada request al config-server hace pull del repo. No requiere reinicio del config-server tras un MR mergeado amain.
| Que cambio | Trazabilidad |
|---|---|
| Codigo de servicio Simappe | Commit en repo del licenciante + MR a develop del cliente + tag stack-<fecha> |
| Configuracion del cliente | Commit en simappeconfig + MR a main del cliente |
| Compose del cliente | Commit local en nodo-01 (no se gitea por ahora) + backup en docker-compose.yml.bak.<timestamp> |
.env del cliente |
NO se versiona en Git. Backup en gestor de secretos del cliente |
| Imagenes Docker | Tag en el registry interno + digest sha256 registrado en log del deploy |
# Status de TODOS los containers
docker ps --format "table {{.Names}}\t{{.Status}}" | grep -E "simappe|nebula"
# Versiones reales corriendo (banner Spring Boot)
for c in simappe-admin simappe-client simappe-oauth2-server simappe-gateway-server nebula-masters nebula-accounting-core; do
echo "--- $c ---"
docker logs --tail 200 $c 2>&1 | grep -E "::.*v[0-9]" | head -2
done
# Profiles activos
for c in simappe-admin simappe-client simappe-oauth2-server simappe-gateway-server; do
echo "--- $c ---"
docker logs --tail 500 $c 2>&1 | grep "profiles are active" | tail -1
done
# Errores recientes globales
for c in simappe-admin simappe-client simappe-oauth2-server simappe-gateway-server nebula-masters nebula-accounting-core; do
errs=$(docker logs --since 15m $c 2>&1 | grep -iE "ERROR|FATAL|Caused by" | head -3)
if [ -n "$errs" ]; then echo "--- $c ---"; echo "$errs"; fi
done
# JpaPasswordEncryption inicializado (debe aparecer en Admin, accounting-core, masters)
for c in simappe-admin nebula-masters nebula-accounting-core; do
echo "--- $c ---"
docker logs --tail 1000 $c 2>&1 | grep -iE "JpaPasswordEncryption" | tail -2
done
# Config-server sirviendo correctamente (sample)
curl -s http://localhost:8890/simappe-admin/dev | python3 -m json.tool | head -20
| Documento | Relacion |
|---|---|
| Resumen Ejecutivo | Contexto del upgrade |
| Migracion Multitenant F1-F5 | Detalle de las features que se activan |
| Incidentes Resueltos | Casos historicos de configuracion fallida |
| Flujo de Arranque Local | Equivalente local del procedimiento de arranque |
| Version | Fecha | Autor | Descripcion |
|---|---|---|---|
| 1.0.0 | 2026-05-24 | Carlos Torres | Estrategias operativas del upgrade stack-2026-05-23 |