Curso de Jenkins: Apuntes Profesionales de CI/CD

Índice General

  1. Introducción a Jenkins y Conceptos Básicos
  2. El Paradigma CI/CD (Integración y Entrega Continua)
  3. Requisitos de Sistema e Infraestructura
  4. Instalación y Configuración del Entorno con Docker
  5. Resolución de Problemas Frecuentes (Troubleshooting)
  6. Pipelines de Jenkins y Ejecución Parametrizada
  7. Caso Práctico: Integración Completa con Cypress y Docker

1. Introducción a Jenkins y Conceptos Básicos

Jenkins es un servidor de automatización de código abierto líder en la industria. Su función principal es facilitar la orquestación de flujos de trabajo automatizados que transforman el código fuente en un producto listo para producción.

Responsabilidades Clave de Jenkins

Gracias a su ecosistema modular con más de 1800 plugins, es altamente extensible y se conecta nativamente con herramientas críticas como Git, Docker, Kubernetes, AWS, SonarQube, entre otras.

2. El Paradigma CI/CD (Integración y Entrega Continua)

Para comprender la utilidad de los Pipelines (bloques de código que definen los pasos del ciclo de desarrollo), es vital dominar las diferencias entre CI y CD:

Concepto Definición Operativa Beneficios Principales
Integración Continua (CI) Práctica de fusionar los cambios de código de los desarrolladores en un repositorio central de forma frecuente. Cada integración desencadena una compilación y pruebas automatizadas. Detección temprana de errores, reducción de conflictos de mezcla (merge) y feedback inmediato para el equipo.
Entrega Continua (CD) Extensión de la CI que automatiza el despliegue del software en entornos de prueba o producción. Permite realizar lanzamientos pequeños y frecuentes de forma segura. Reducción del tiempo de salida al mercado (Time-to-Market), entregas predecibles y mejoras iterativas constantes.

3. Requisitos de Sistema e Infraestructura

Para ejecutar una instancia estable de Jenkins en entornos locales o de servidores dedicados, se deben cumplir los siguientes requerimientos mínimos:

4. Instalación y Configuración del Entorno con Docker

La instalación mediante contenedores Docker garantiza que Jenkins se ejecute en un ambiente controlado e independiente. A continuación se listan los comandos ordenados para preparar el sistema operativo anfitrión (basado en distribuciones Linux/Ubuntu):

# 1. Actualizar los repositorios locales e índices del sistema
sudo apt update
sudo apt upgrade -y

# 2. Instalar paquetes de soporte para la transferencia segura de datos
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y

# 3. Añadir la llave GPG oficial de Docker para validar la autenticidad de los paquetes
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# 4. Sincronizar nuevamente e instalar Docker Community Edition (CE) junto a su CLI
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y

# 5. Validar la correcta instalación de la plataforma verificando su versión
docker --version

# 6. Añadir el usuario actual al grupo de Docker para ejecutar comandos sin 'sudo'
sudo usermod -aG docker $USER

# 7. Aplicar de manera inmediata los cambios de grupo en la sesión actual
newgrp docker

5. Resolución de Problemas Frecuentes (Troubleshooting)

Error de Conexión al Demonio de Docker

Si al ejecutar un comando de verificación como docker run hello-world se arroja el siguiente error:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Causa: El servicio del motor de Docker no se ha iniciado o se encuentra detenido en el sistema operativo.

Solución: Inicializar el servicio a través del gestor del sistema ejecutando:

sudo systemctl start docker

6. Pipelines de Jenkins y Ejecución Parametrizada

Los pipelines paramétricos añaden una capa de flexibilidad que permite al operador seleccionar variables dinámicas antes de iniciar la ejecución de los flujos de trabajo (utilizando la opción Build with Parameters en la interfaz de usuario).

Flujo de Trabajo Típico de Ejecución

  [ Jenkins clona el repositorio ] 
                 ↓
[ Descarga de la imagen de Docker requerida ]
                 ↓
 [ Ejecución interna de las pruebas (Testing) ]

7. Caso Práctico: Integración Completa con Cypress y Docker

Para asegurar que los tests se ejecuten correctamente en Jenkins, el repositorio de código fuente debe contener al menos la siguiente estructura básica:

tu-repositorio/
 ├─ package.json
 └─ cypress/
     └─ e2e/
         └─ acceso-a-index.cy.js

Código Completo del Declarative Pipeline

Este archivo de configuración (Jenkinsfile) define los parámetros de entrada (archivo de especificación y navegador) y orquesta las fases del ciclo mediante contenedores Docker aislados:

pipeline {
    agent any
    
    parameters {
        string(
            name: 'SPEC', 
            defaultValue: 'acceso-a-index.cy.js', 
            description: 'Especifica el archivo de prueba de Cypress a ejecutar'
        )
        choice(
            name: 'BROWSER', 
            choices: ['chrome', 'firefox'], 
            description: 'Selecciona el navegador para ejecutar las pruebas'
        )
    }
    
    options {
        // Habilitar salida de colores ANSI en la consola de Jenkins
        ansiColor('xterm')
    }
    
    stages {
        stage('Checkout') {
            steps {
                // Descarga automática del código fuente desde el SCM configurado
                checkout scm
            }
        }
        
        stage('Testing') {
            steps {
                echo "Ejecutando pruebas de Cypress en ${params.SPEC} usando el navegador ${params.BROWSER}"
                script {
                    // Descarga e inicia la imagen oficial de Cypress anulando el entrypoint por defecto
                    docker.image('cypress/included:13.7.0').inside('--entrypoint=""') {
                        sh """
                        npm install
                        npx cypress run --spec cypress/e2e/${params.SPEC} --browser ${params.BROWSER}
                        """
                    }
                }
            }
        }
        
        stage('Deploying') {
            steps {
                echo "Desplegando la aplicación en el entorno correspondiente..."
            }
        }
    }
    
    post {
        always {
            echo "Pipeline finalizado. Limpiando el entorno de ejecución..."
        }
    }
}