Jenkins SCO — Deploy Server
Jenkins centralizado para el despliegue de software en terminales SCO (Self-Checkout) en producción.
Estructura del repositorio
.
├── docker-compose.yml
└── data/
└── jenkins/
├── Dockerfile # Imagen Jenkins con plugins
├── jenkins.yaml # Configuración JCasC (nodos, seguridad, jobs)
├── deploy/
│ └── install.sh # Script desplegado en cada SCO
└── pipelines/
└── Jenkinsfile.ralph # Pipeline del cliente Ralph
Arquitectura
- Jenkins master: corre en Docker en el servidor Minio (
186.67.82.140). - Agentes (SCOs): cada terminal SCO conecta al master vía JNLP (puerto 50000). El proceso del agente corre como
root. - Storage: Minio almacena el software de cada cliente en buckets separados (ej: bucket
ralph).
Labels de agentes
Formato: sco <cliente> <tienda>
| Cliente | Tienda | Agentes |
|---|---|---|
| ralph | yabucoa | sco02–sco07 |
| ralph | san-lorenzo | sco03–sco06 |
| ralph | rio-grande | sco01–sco06 |
Levantar el servidor
docker compose up -d --build
Jenkins queda disponible en http://<server-ip>:8080 (admin / H0l4mund0!).
Conectar un agente SCO
-
Descargar el agente desde Jenkins:
curl -sO http://<server-ip>:8080/jnlpJars/agent.jar mv agent.jar /opt/jenkins-agent/agent.jar -
Obtener el secret del nodo: en Jenkins → Manage Jenkins → Nodes → (nombre del nodo).
-
Crear el servicio systemd en el SCO:
# /etc/systemd/system/jenkins-agent.service [Unit] Description=Jenkins Agent After=network.target [Service] User=root ExecStart=/usr/bin/java -jar /opt/jenkins-agent/agent.jar \ -url http://<server-ip>:8080/ \ -secret <SECRET> \ -name "<nombre-del-nodo>" \ -workDir "/opt/jenkins-agent" Restart=always RestartSec=10 [Install] WantedBy=multi-user.target -
Habilitar y arrancar:
systemctl daemon-reload systemctl enable --now jenkins-agent
Ejecutar un deploy
- En Jenkins, abrir el job
deploy-ralph. - Click en Build with Parameters.
- Seleccionar la tienda destino en el dropdown (yabucoa / san-lorenzo / rio-grande).
- El pipeline despliega
install.sh ralphen paralelo en todos los SCOs online de esa tienda.
Qué hace install.sh
Recibe el nombre del cliente como argumento ($1):
- Genera config de rclone apuntando al Minio local.
- Sincroniza el bucket
$CUSTOMERdesde Minio hacia/opt/sco/en el SCO (excluyendo datos persistentes del backend). - Ajusta permisos en
/opt/sco/. - Instala servicios systemd desde
/opt/sco/resources/services/. - Configura autostart del usuario
sco. - Instala crontabs de
rootysco. - Instala paquetes Python offline.
- Carga imágenes Docker.
- Inicializa carpetas y archivos de base de datos del cpi-server.
- Genera
engine.propertiespara SymmetricDS (solo en primera instalación).
Operaciones de mantenimiento
Agregar un nuevo cliente
El deploy es idéntico para todos los clientes: el install.sh recibe el nombre del cliente como $1.
Solo cambia el nombre del job, el Jenkinsfile, y los nodos registrados.
1. Registrar los nodos en data/jenkins/jenkins.yaml
Bajo la clave nodes, añadir un bloque por cada SCO del cliente:
- permanent:
name: "nuevocliente-tienda1-sco01"
labelString: "sco nuevocliente tienda1"
remoteFS: "/opt/jenkins-agent"
numExecutors: 1
retentionStrategy: "always"
launcher:
inbound: {}
Repetir para cada combinación tienda/SCO. Convención de nombres:
- Nombre del nodo:
<cliente>-<tienda>-<sco>(ej:ralph-yabucoa-sco02) - Label:
sco <cliente> <tienda>(ej:sco ralph yabucoa)
2. Crear el Jenkinsfile en data/jenkins/pipelines/Jenkinsfile.<cliente>
Copiar Jenkinsfile.ralph y ajustar dos cosas:
// En parameters: listar las tiendas del nuevo cliente
choices: ['tienda1', 'tienda2', 'tienda3'],
// En el stage Deploy: cambiar el nombre del cliente (dos lugares)
def labelExpr = "nuevocliente && ${params.TIENDA}"
sh "bash install.sh 'nuevocliente'"
3. Agregar el job en data/jenkins/jenkins.yaml
Al final de la sección jobs:
- script: |
pipelineJob('deploy-nuevocliente') {
description('Deploy de install.sh a los SCOs de NuevoCliente.')
definition {
cps {
script(new File('/opt/jenkins/Jenkinsfile.nuevocliente').text)
sandbox(true)
}
}
}
4. Montar el Jenkinsfile en docker-compose.yml
volumes:
- ./data/jenkins/pipelines/Jenkinsfile.nuevocliente:/opt/jenkins/Jenkinsfile.nuevocliente:ro
5. Recrear el contenedor
docker compose up -d --build
En el servidor remoto:
# Copiar los archivos modificados al servidor primero, luego:
docker compose up -d --build
Agregar una tienda a un cliente existente
1. Añadir los nodos de la nueva tienda en jenkins.yaml (un bloque por SCO, igual que arriba).
2. Agregar la tienda al dropdown del Jenkinsfile del cliente:
choices: ['yabucoa', 'san-lorenzo', 'rio-grande', 'nueva-tienda'],
3. Aplicar en el servidor:
docker compose restart jenkins
No hace falta rebuild completo si solo cambia jenkins.yaml o el Jenkinsfile — el contenedor los monta como volúmenes y JCasC los recarga.
Si agregaste nodos nuevos pero no reiniciaste Jenkins, también podés recargar desde la UI: Manage Jenkins → Configuration as Code → Reload existing configuration.
Agregar un SCO a una tienda existente
Solo tocar jenkins.yaml: añadir el nodo nuevo bajo nodes.
- permanent:
name: "ralph-yabucoa-sco08"
labelString: "sco ralph yabucoa"
remoteFS: "/opt/jenkins-agent"
numExecutors: 1
retentionStrategy: "always"
launcher:
inbound: {}
Luego recargar la configuración:
docker compose restart jenkins
# o desde la UI: Manage Jenkins → Configuration as Code → Reload existing configuration
Una vez que Jenkins lo reconoce, conectar el agente en el SCO físico (ver sección "Conectar un agente SCO").