Cómo ejecutar contenedores de Docker con Maven exec-maven-plugin

0
257
Maven Docker Exec

Cuando estamos usando Maven y queremos levantar contenedores de Docker para, por ejemplo, ejecutar los tests de integración, es bastante típico usar alguno de los plugins específicos que existen. Donde a día de hoy posiblemente el más habitual es docker-maven-plugin de Fabric8.

Estos plugins suelen ser un recubrimiento sobre un cliente de Docker que al final se conecta con el Docker daemon para realizar las acciones necesarias. Si bien para casos sencillos son muy convenientes, y de hecho seguramente deberían ser la opción por defecto, el problema que tienen este tipo de plugins es que están más pensados para crear imágenes en vez de ejecutarlas, y sobre todo si queremos levantar distintos contenedores con dependencias entre ellos… la cosa se complica 😅.

En este tutorial vamos a ver cómo podemos usar el simple plugin de Maven exec-maven-plugin para quitarnos estos intermediarios y hacer lo que queramos directamente con el comando docker.

De hecho en este tutorial utilizaremos el comando docker compose que nos permitirá más flexibilidad a la hora de levantar distintos contenedores de forma simultánea.

Podéis encontrar todo el código de este tutorial en: https://github.com/alejandropg/tutorial-maven-docker-exec. Incluido un ejemplo de cómo ejecutarlo integrado con los GitHub Actions.

Índice

  1. Entorno
  2. Maven pom.xml
  3. El script para preparar el arranque de los tests de integración: docker-compose-it-up.sh
  4. El script para limpiar el entorno después de los tests de integración: docker-compose-it-down.sh
  5. La configuración de docker compose
  6. Conclusiones
  7. Sobre el autor


1. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 16″ (Apple M1 Pro, 32GB LPDDR5, 1TB SSD).
  • Sistema Operativo: macOS Monterey 12.0.1.
  • Java version: 11.0.13, vendor: Azul Systems, Inc., arch: “aarch64”, family: “mac”.
  • Apache Maven 3.8.3.
  • Docker Desktop 4.1.1 (69879) y también probado en 4.2.0 (70708).


2. Maven pom.xml

Para usar el plugin exec-maven-plugin simplemente haremos la siguiente configuración en nuestro Maven pom.xml.

Aquí se ve como simplemente nos enganchamos a la fase de pre-integration-test y post-integration-test para ejecutar un script para arrancar “up” y parar “down” el Docker compose.

He elegido usar un script y no hacerlo directamente aquí porque eso nos puede dar mucha flexibilidad a la hora de ejecutar cualquier otro tipo de configuración de arranque que necesitemos para nuestros tests de integración. Lo veremos más adelante con un ejemplo.


3. El script para preparar el arranque de los tests de integración: docker-compose-it-up.sh

docker-compose-it-up.sh es un script sh normal y corriente, por lo que tendremos a nuestro alcance toda la potencia de la shell.

Este script seguramente es lo más complicado de todo el tutorial. Al principio encontramos un par de funciones de ayuda donde el propósito de estas es una pequeña optimización para no hacer el docker compose pull constantemente y ahorrar unos preciosos segundos cuando lo estamos ejecutando en local. Es decir, si analizamos en detalle la función _docker_compose_pull_image, podemos ver que lo que hace es comprobar si la imagen ya está en local o no. De no encontrarla intentará hacer un pull de todo el Docker compose.

Luego la otra parte con “truco” es el uso del expectLa intención del expect es no terminar la ejecución del script hasta que se encuentre en la salida la línea especificada. De esta forma garantizamos que los tests de integración no empezarán a ejecutarse hasta que esté debidamente levantado el contenedor.

Esto sería el equivalente a, por ejemplo, cuando usando el docker-maven-plugin de Fabric8 y hacemos:

También se define un timeout de 5 segundos, de forma que si en este tiempo no se encuentra la línea especificada el script terminará abruptamente. Precisamente por este timeout es por lo que separamos el pull de las imágenes del up del Docker compose, ya que si no lo separamos será muy fácil que salte el timeout la primera vez que lo ejecutemos, cuando intente descargar las imágenes.


4. El script para limpiar el entorno después de los tests de integración: docker-compose-it-down.sh

De nuevo docker-compose-it-down.sh es un script sh normal donde podremos ejecutar todo lo que necesitemos para limpiar el entorno tras ejecutar los tests de integración.

Se ve como en nuestro caso simplemente paramos el Docker compose. Además aquí son comandos normalitos y no necesitamos usar ningún “truco” como vimos con el expect en el punto anterior.


5. La configuración de docker compose

Para configurar el Docker compose usamos un fichero de configuración normal y corriente: docker-compose-it.yml

En el ejemplo solo levantamos un servicio, pero como es un fichero normal de configuración de Docker compose podríamos hacer cualquier cosa que este permita, como levantar n servicios, con dependencias entre ellos, montar volúmenes…


6. Conclusiones

Con este ejemplo estamos yendo un poco a “bajo nivel”, pero si os fijáis tampoco tanto, puesto que hay pocas lineas que no tuviéramos que poner de todas formas: nombre de la imagen, nombre de los volúmenes, en que fase del ciclo de Maven queremos engancharlo…

Y sin embargo conseguimos un aumento de flexibilidad enorme, ya que ponemos a nuestro alcance toda la potencia de la shell, de Docker y de Docker compose.

Así que desde luego esta puede ser una buena opción a tener en cuenta si vemos que se nos complica la cosa a la hora de levantar contenedores dentro del ciclo de vida de Maven.


7. Sobre el autor

Alejandro Pérez García (@alejandropgarci).

Ingeniero en Informática (especialidad de Ingeniería del Software) y Certified ScrumMaster.

Socio fundador de Autentia Real Business Solutions S.L. – “Soporte a Desarrollo”.

Dejar respuesta

Please enter your comment!
Please enter your name here