Integración y entrega continua con GitLab sobre Docker

Escrito por el .
planeta-codigo software software-libre
Enlace permanente Comentarios

GitLab

GitLab es una herramienta muy completa, una de las necesidades de los proyectos es tener teses y que estos se ejecuten con cada commit para asegurar que los cambios no introducen errores en las funcionalidades cubiertas por los teses, esto es la integración continua. La entrega inmediata es una vez que los teses se han ejecutado correctamente hacer el despliegue en los servidores de forma pasa el tiempo mínimo entre que una funcionalidad está desarrollada y esta se puede utilizar.

GitLab proporciona integración continua (Continuos Integration, CI) y entrega continua (Continuos Delivery, CD) sin necesidad de una herramienta externa más especializada como es Jenkins. En el siguiente ejemplo muestro como configurar GitLab para crear uno o varios runner que son los que realizan las acciones de integración y entrega continua y el archivo descriptor .gitlab-ci.yml en formato yaml que define las acciones específicas del proyecto que se ejecutarán con cada commit en el repositorio Git.

Jenkins es una herramienta más especializada que también sirve para realizar integración y entrega continua. En la página GitLab vs Jenkins se comparan las características de ambas herramientas, aunque en esa página de comparación GitLab está indicando que tiene algunas características más y aunque no tuviera tantas para la mayoría de los casos de uso es más que suficiente con la ventaja de no necesitar una herramienta más al estar estar ya integrado en GitLab que ofrece además del repositorio de código fuente, una wiki o un páginas para un sitio web.

Para realizar integración y entrega continua hay definir las acciones, tareas y comandos de los que se componen del pipeline específico para el proyecto, la descripción del pipeline se define en un archivo .gitlab-ci.yml que se añade en el directorio raíz del código fuente del proyecto en su repositorio de Git. El pipeline según las necesidades del proyecto consta de varios pasos o steps que se ejecutan de forma secuencial. Si en un mismo paso hay varias acciones estas se ejecutan de forma paralela. En el ejemplo de proyecto test con un programa Hola Mundo con Java y usando la herramienta de construcción Gradle el pipeline consta de las acciones de compilación y de ejecución de pruebas unitarias y creación de documentación javadoc. La tarea de Gradle build en un proyecto Java realiza la compilación, ejecución de pruebas unitarias y genera el artefacto resultado el el directorio build/distributions y la librería jar con las clases compiladas en build/libs, la tarea javadoc genera la documentación Javadoc de las clases del proyecto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
image: openjdk:8-jdk-alpine

stages:
  - build

build:
  stage: build
  script:
    - ./gradlew --no-daemon build javadoc
  artifacts:
    paths:
      - build/distributions/gradle.zip
      - build/docs/javadoc/
gitlab-ci.yml

Añadido el archivo del pipeline al código fuente del proyecto hay que definir un runner que se encargará de ejecutarlo con cada commit que se envíe al repositorio de código fuente. Hay que registrarlo y se necesita un token que se puede obtener desde el área de administración en Overview > Runners.

Runners

GitLab Runners

Al registrarlo hay que especificar el tipo de runner, hay varios tipos, en este caso se usa el de docker para ejecutar el pipeline dentro de un contenedor de Docker. En en archivo de Docker Compose es necesario que el runner pueda comunicarse con el servicio de Docker, para ello como punto de montaje del contenedor de gitlab-runner se especificar el archivo docker.sock.

1
2
$ docker exec -it gitlab-runner gitlab-runner register --url "https://gitlab" --registration-token "RhoFva9z8Ri6cuDYbXN1" --tag-list "gitlab-runner-01" --run-untagged "true" --locked "false" --executor "docker"

add-gitlab-runner.sh

En este ejemplo y con este pipeline el artefacto distribuible de la aplicación y el Javadoc se almacena en GitLab estando accesible para su descarga desde el panel lateral una vez finalizado el pipeline.

Pipelines Pipeline

Pipeline

El descriptor usando Docker Compose que define el servicio de GitLab y otro para GitLab Runner es el siguiente. El nombre de dominio que he utilizado para el servidor es gitlab y ha de añadirse al archivo /etc/hosts para que sea resuelto localmente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
version: '3.4'

services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    container_name: gitlab
    hostname: 'gitlab'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        gitlab_rails['gitlab_shell_ssh_port'] = 8022
        external_url 'https://gitlab'
        nginx['ssl_certificate'] = '/etc/gitlab/ssl/gitlab.crt'
        nginx['ssl_certificate_key'] = '/etc/gitlab/ssl/gitlab.key'
        pages_external_url 'https://gitlab'
        pages_nginx['redirect_http_to_https'] = true
        pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.crt"
        pages_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.key"        
    networks:
      gitlab:
        aliases:
          - gitlab
    ports:
      - '8022:22'
      - '8080:80'
      - '8443:443'
    volumes:
      - 'gitlab-config-volume:/etc/gitlab'
      - 'gitlab-log-volume:/var/log/gitlab'
      - 'gitlab-data-volume:/var/opt/gitlab'
      - './docker-volumes/gitlab/ssl:/etc/gitlab/ssl'

  gitlab-runner:
    image: 'gitlab/gitlab-runner:latest'
    container_name: gitlab-runner
    environment:
      - 'DOCKER_NETWORK_MODE=gitlab_gitlab'
    links:
      - gitlab
    networks:
      - gitlab
    volumes:
      - 'gitlab-runner-config-volume:/etc/gitlab'
      - './docker-volumes/gitlab/ssl/gitlab.crt:/etc/gitlab-runner/certs/ca.crt'
      - '/var/run/docker.sock:/var/run/docker.sock'

volumes:
  gitlab-config-volume:
  gitlab-log-volume:
  gitlab-data-volume:
  gitlab-runner-config-volume:

networks:
  gitlab:
    driver: bridge
docker-compose-all.yml

En la sección de referencia hay unos buenos enlaces de documentación de GitLab sobre la integración continua, despliegue continuo y entrega continua.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
docker-compose -f docker-compose-all.yml up


Comparte el artículo: