Usando Jenkins y Docker

0
24750

Introducción

En este tutorial se va a montar un entorno de integración continua usando Jenkins y contenedores de Docker. Jenkins se va a utilizar junto con el plugin de Blue Ocean, que ofrece una nueva interfaz de usuario y facilita la creación de pipelines declarativas usando un Jenkinsfile.

Ya que todas las herramientas van a ir montadas en un contenedor de Docker para este tutorial se recomienda tener un conocimiento básico de su uso. Recomiendo este tutorial de introducción a Docker: Dockeriza tu API explicado para principiantes.

En el siguiente repositorio hay un proyecto muy simple de React que es el que se va a utilizar en Jenkins. Mediante un docker-compose se va a levantar un contenedor de Jenkins y otro de SonarQube.

Indice

  1. Introducción
  2. Entorno
  3. Preparación de Docker
  4. Configuración de Jenkins
  5. Referencias
  6. Conclusiones

Entorno

Para realizar este tutorial se ha usado:

  • MacBook Pro 15” (2015).
  • Procesador i7 de 4 núcleos (2015).
  • Memoria 16GB 1600MHz DDR3.
  • macOS Catalina 10.15.4

Docker 2.2.0.5 y Jenkins 1.23.2.

Preparación de Docker

La instalación se va a realizar usando una imagen de docker con Jenkins junto con el plugin instalado. Esta es una forma muy cómoda y limpia de usar Jenkins, en la que los cambios persisten en el volumen definido. Se define el siguiente docker-compose.yml.

version: "3"

services:
  jenkins:
    user: root
    image: "jenkinsci/blueocean:1.23.1"
    ports:
      - "8080:8080"
    volumes:
      - ./jenkins_home:/var/jenkins_home
      - /usr/local/bin/docker:/usr/bin/docker
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - mynet
    
networks:
  mynet:
    driver: bridge

Vamos a explicar el archivo paso por paso. En el siguiente bloque se define el contenedor que tiene de nombre “jenkins”:

  jenkins:
    user: root
    image: "jenkinsci/blueocean:1.23.1"
    ports:
      - "8080:8080"
    volumes:
      - ./jenkins_home:/var/jenkins_home
      - /usr/local/bin/docker:/usr/bin/docker
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - mynet

La imagen que usa este contenedor es la siguiente jenkinsci/blueocean. El puerto que usa Jenkins es el 8080 y ese mismo puerto va a ser el que se va a exponer en el host, mediante la anotación ports. Es necesario especificar user:root para que Jenkins pueda hacer git clean en el directorio del repositorio cada vez que empiece la pipeline. Los volúmenes a usar son los tres siguientes:

  • El primero es la carpeta de ./jenkins_home que va a tener toda la instalación de jenkins (plugins y configuración). Es el working directory de la imagen. Como se introduce como ruta relativa se debe ejecutar el docker-compose desde la carpeta padre de jenkins_home.
  • En segundo lugar se comparten los binarios de docker. Esto se hace para que el contenedor de Jenkins pueda usar los comandos de docker y los contenedores que se creen debido al flujo de CI lo hagan usando el mismo socket.
  • En tercer lugar se comparte docker.sock, por lo dicho en el punto anterior. Este archivo es el socket al que el proceso de Docker escucha.

Ejecutar el docker-compose

Para ejecutar el docker-compose.yml se ejecuta el siguiente comando desde el directorio en el que se encuentre el archivo. El argumento de -d ejecuta los contenedores en modo detached.

$ docker-compose up -d

Tanto el contenedor de jenkins como el de sonar van a estar en la misma red, cuyo nombre es mynet, pero docker-compose va a añadirle como prefijo el nombre del directorio en el que se encuentra. En nuestro caso el directorio de trabajo se llama jenkins-blue-ocean-tutorial. De forma que si se quiere levantar un contenedor desde jenkins hay que asignarle como red jenkins-blue-ocean-tutorial_mynet. Si se hace un $ docker network ls se muestran todas las redes que hay creadas en Docker:

Configuración de Jenkins

Una vez ejecutado $ docker-compose up -d se puede ir al navegador a http://localhost:8080/, donde se accede a nuestra instancia de Jenkins. La contraseña inicial de administrador de Jenkins se encuentra en el contenedor de Jenkins en /var/jenkins_home/secrets/initialAdminPassword, pero como la carpeta jenkins_home se encuentra en un volumen la podemos encontrar en la ruta que hayamos definido nosotros.

Tenemos que elegir si instalar plugins por defecto o manualmente. En este caso se selecciona la instalación de los plugins por defecto. Algunos plugins han fallado, pero le damos al botón de continuar ya que se arreglaran posteriormente en la configuración.

Downgrade del plugin Github API

Se ha tenido que realizar un downgrade a la versión de Github API 1.106 (desde la 1.22) debido a un bug con el formulario del access token de Github.

Para realizar dicho downgrade se descarga el archivo “.hpi” con la versión 1.106 de aquí y luego se instala desde la configuración de Jenkins desde Manage Plugins > Advance > Upload Plugin. Se puede obtener más información en esta pregunta de Stack Overflow: Jenkins blue ocean plugin fails to connect to github

Usar Blue Ocean

Para empezar a usar Blue Ocean se tiene que acceder pulsando el botón llamado “Open Blue Ocean” de la barra lateral. Al hacer esto se carga una nueva interfaz. Esta interfaz consiste en una barra de navegación superior en la que se muestran las funciones principales de Blue Ocean y una parte inferior en la que se muestra la información específica de la funcionalidad seleccionada.

En la parte inferior aparece un modal en el que se sugiere crear una nueva pipeline. Este botón nos va a llevar a un formulario en el que vamos a introducir la información más básica de nuestro pipeline para empezar a trabajar.

En el tutorial se va a usar Github como repositorio y para ello necesitamos un token. El token tiene que tener los permisos de “repo” y de “user:email”.

Creating a personal access token for the command line

En Blue Ocean existe un link “Create an access token here” que lleva directamente a la creación de acces token en Github con los parámetros correctos, lo cual es muy conveniente y rápido. Recordad que el token solo se muestra una vez al generarlo por lo que no hay que olvidarlo copiar al portapapeles.

Finalmente se selecciona la organización y el repositorio del proyecto. El repositorio para este tutorial no es necesario que contenga nada, ya que se usará una imagen de docker con npm para crear un proyecto de ejemplo de react desde Jenkins para simplificar el proceso.

Jenkinsfile

Blue Ocean va a crear un archivo “Jenkinsfile” en el que toda la pipeline va a estar representada por código. Esto tiene varias ventajas:

  • Registro de los cambios a través de control de versiones.
  • Existe una única fuente fiable (source of truth) para la pipeline.

Ahora mismo hay que tener cuidado al editar el archivo directamente ya que si hay algún error en la vista de Blue Ocean no van a mostrarse ciertos menús de edición y puede haber comportamientos inesperados. Esto se puede ver abriendo el inspector y ver si hay algún error en la consola. Se puede obtener más información en la documentación de Jenkins aquí.

Crear una pipeline

El flujo que quiere realizar es el siguiente: dado un proyecto de React instalar las dependencias del proyecto y posteriormente ejecutar la batería de tests. El proceso a seguir para materializar este pipeline en Jenkins es el siguiente:

  1. Dentro de la configuración de la pipeline seleccionar como agente docker y especificar en el campo de imagen node:12 y como argumento –network jenkins-blue-ocean-tutorial_mynet .El parámetro –network especifica el nombre de la red en la que está el contenedor de Jenkins.Guardar la configuración.
  2. En la figura central pulsar en el icono de «+», que abrirá un panel para crear una fase nueva.
  3. Posteriormente en dicho panel introducir el nombre de la fase como “Build” y seleccionar en el paso “Add Step” la opción de “Shell Script”. De este modo se puede introducir en una caja de texto los comandos de shell que se quieren ejecutar. Introducir en la caja de texto cd ./example-react; npm install .
  4. Guardar con el botón de Save y en el modal que aparece especificar un mensaje de commit.

Ahora aparecerá la vista principal de Blue Ocean en la que se muestra nuestra nueva pipeline ejecutándose. Una vez termine aparecerá en verde.

Si se clica dentro del pipeline se va a la vista de detalle en el que se pueden abrir los logs para cada uno de los pasos.

Añadiendo una fase de test

Para terminar se va a añadir una nueva fase en la que se van a ejecutar los test. En el proyecto de React los archivos de test son aquellos que tienen «.spec» en el nombre.

  1. Se añade una nueva fase llamada “Test”.
  2. Crear un paso de shell con el siguiente contenido:
$ cd ./example-react; npm run test -- --coverage --watchAll=false

Al terminar el pipeline se muestra este resultado en verde, todo ha salido bien.

Referencias

Conclusiones

A lo largo de este tutorial se ha creado un entorno de CI para un proyecto de React usando Docker, que ofrece varias ventajas. Principalmente el uso de Docker, con docker-compose, tiene la ventaja de agrupar la configuración de Jenkins en un solo archivo como código. Además de que se dispone de multitud de imágenes con distintas configuraciones listas para usar que ahorran mucho tiempo. De igual forma la pipeline que se ha creado mediante una interfaz queda reflejada como código en un Jenkinsfile.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad