Evitando que Jenkins Elimine Procesos en Segundo Plano

Problema

Al ejecutar scripts en Jenkins que utilizan nohup para iniciar aplicaciones en segundo plano, estos procesos son terminados automáticamente cuando el trabajo de Jenkins finaliza. Por ejemplo, al intentar ejecutar:

nohup /usr/java/bin/java -Xms1024m -Xmx1024m -jar /ruta/miapp-2.0.0.jar --spring.config.location=archivo.properties >/ruta/registro.log 2>&1 &

El proceso parece iniciarse correctamente durante la ejecución en Jenkins, pero una vez que el trabajo finaliza, la aplicación deja de funcionar.

Diagnóstico

1. La ejecución directa del comando nohup en la terminal funciona sin problemas
2. Los scripts que no utilizan nohup se ejecutan correctamente a través de Jenkins

Esto indica que el problema específicamente ocurre cuando se utilizan comandos nohup dentro de los scripts ejecutados por Jenkins.

Causa

Jenkins, por diseño, termina todos los procesos derivados que fueron iniciados durante la ejecución de un trabajo. Esto se basa en el identificador de construcción (BUILD_ID) para reconoecr los procesos asociados a una tarea específica.

Cuando Jenkins finaliza un trabajo, busca y mata todos los procesos que tienen el BUILD_ID del trabajo actual. Como nohup inicia un nuevo proceso, este es identificado y terminado.

Soluciones

1. Modificar el BUILD_ID

Al estalbecer BUILD_ID en un valor diferente al que utiliza Jenkins, el proceso ya no será identificado como derivado del trabajo y continuará ejecutándose:

#!/bin/bash
BUILD_ID=conservarProceso
nohup /usr/java/bin/java -Xms1024m -Xmx1024m -jar /ruta/miapp-2.0.0.jar --spring.config.location=archivo.properties >/ruta/registro.log 2>&1 &

2. Configurar Parámetros de Inicio de Jenkins

Modificar el archivo de configuración de Jenkins para deshabilitar el árbol de procesos:

En JAVA_OPTS de Jenkins, agregar: -Dhudson.util.ProcessTree.disable=true

Este cambio requiere reiniciar Jenkins y afectará a todos los trabajos sin necesidad de modificar cada script.

3. Utilizar el Comando 'at'

En lugar de nohup, se puede utilizar el comando 'at' programando la ejecución inmediata:

#!/bin/bash
set +e
echo "/usr/java/bin/java -Xms1024m -Xmx1024m -jar /ruta/miapp-2.0.0.jar --spring.config.location=archivo.properties >/ruta/registro.log" | at now

Este método requiere que el servicio 'atd' esté en ejecución.

Solución para Pipeline Jenkins

En entornos de Jenkins Pipeline, se debe utilizar JENKINS_NODE_COOKIE en lugar de BUILD_ID:

node {
    withEnv(['JENKINS_NODE_COOKIE=conservarProceso']) {
        sh 'nohup /usr/java/bin/java -Xms1024m -Xmx1024m -jar /ruta/miapp-2.0.0.jar >/ruta/registro.log 2>&1 &'
    }
}

Para más información, consultar la documentación oficial de Jenkins: https://www.jenkins.io/doc/book/managing/spawning-processes/#workarounds

Etiquetas: Jenkins procesos nohup BUILD_ID Pipeline

Publicado el 7-3 05:51