Dockerización de una aplicación Spring Boot

En este artículo, cubriremos el proceso de creación de una imagen Docker de una aplicación Spring Boot, usando Dockerfile y Maven y luego ejecutaremos la imagen que creamos...

Visión general

En este artículo, cubriremos el proceso de creación de una imagen Estibador de una [Bota de primavera](https://spring.io/projects/spring- boot), usando Dockerfile y Experto y luego ejecute la imagen que tenemos he creado.

El código fuente de este tutorial se puede encontrar en Github.

Este tutorial asume que tiene Docker instalado en su máquina. Si no, puedes seguir la guía oficial de Instalación de la ventana acoplable según tu sistema operativo.

Si desea leer más sobre Docker, lo cubrimos en detalle en - Docker: una introducción de alto nivel.

La aplicación Spring Boot

Empecemos con una sencilla aplicación Spring Boot. La mejor manera de comenzar con un proyecto básico es visitar Spring Initializr. Seleccione su versión preferida de Spring Boot y agregue la dependencia "Web". ¡Génelo como un proyecto de Maven y ya está todo listo!

Spring Initializr{.img-responsive}

El proyecto incluye un controlador REST simple con un solo mapeo que solo espera un nombre como variable de ruta y luego genera una cadena para saludarlo:

1
2
3
4
5
6
7
8
@RestController
public class DemoController {

  @GetMapping("/greet/{name}")
  public String greeting(@PathVariable String name) {
    return "Hi!! " + name;
  }
}

Para ejecutar la aplicación, use el siguiente comando de Maven desde la carpeta raíz del proyecto:

1
$ mvn spring-boot:run

Como de costumbre, la aplicación se ejecutará en el puerto 8080. Para probar este punto final, navegue en su navegador (o use rizo, [cartero](https://www.getpostman .com/), etc.) a "http://localhost:8080/saludo/john", verá una respuesta similar a:

REST response 1{.img-responsive}

Dockerización de la aplicación Spring Boot

Ahora vamos a dockerizar nuestra aplicación Spring Boot creada anteriormente. Cubriremos los dos enfoques más utilizados:

  • Dockerfile – Especificación de un archivo que contiene comandos nativos de Docker para construir la imagen
  • Maven – Uso de un complemento de Maven para construir la imagen

Dockerización usando Dockerfile

Un Dockerfile es simplemente un archivo .txt normal que incluye comandos nativos de Docker que se utilizan para especificar las capas de una imagen. Para ello, vamos a crear un archivo de texto llamado "Dockerfile":

Docker file{.img-responsive}

El contenido del archivo en sí puede verse así:

1
2
3
4
5
6
7
8
9
FROM java:8-jdk-alpine

COPY ./target/demo-docker-0.0.1-SNAPSHOT.jar /usr/app/

WORKDIR /usr/app

RUN sh -c 'touch demo-docker-0.0.1-SNAPSHOT.jar'

ENTRYPOINT ["java","-jar","demo-docker-0.0.1-SNAPSHOT.jar"]

Echemos un vistazo a los comandos y entendámoslos completamente antes de continuar:

  • FROM – La palabra clave FROM le dice a Docker que use una imagen base determinada como base de compilación. Hemos usado 'java' con la etiqueta '8-jdk-alpine'. Piense en una etiqueta como una versión. La imagen base cambia de un proyecto a otro. Puede buscar imágenes en docker-hub.
  • COPIAR: esto le indica a Docker que copie los archivos del sistema de archivos local a una carpeta específica dentro de la imagen de compilación. Aquí, copiamos nuestro archivo .jar a la imagen de compilación (imagen de Linux) dentro de /usr/app.
  • WORKDIR - La instrucción WORKDIR establece el directorio de trabajo para cualquier instrucción RUN, CMD, ENTRYPOINT, COPY y ADD que siguen en el Dockerfile. Aquí cambiamos el directorio de trabajo a /usr/app para que no tengamos que escribir la ruta larga una y otra vez.
  • EJECUTAR: esto le dice a Docker que ejecute una línea de comando de shell dentro del sistema de destino. Aquí prácticamente solo "tocamos" nuestro archivo para que tenga su tiempo de modificación actualizado (Docker crea todos los archivos contenedores en un estado "sin modificar" por defecto).
  • PUNTO DE ENTRADA: esto le permite configurar un contenedor que se ejecutará como un ejecutable. Es donde le dices a Docker cómo ejecutar tu aplicación. Sabemos que ejecutamos nuestra aplicación spring-boot como java -jar <app-name>.jar, así que la colocamos en una matriz.

Se puede encontrar más documentación en la página Referencia del archivo acoplable.

Antes de continuar, necesitamos un archivo .jar de Spring Boot. Este archivo se usará para crear la imagen de Docker como se mencionó anteriormente.

Ejecute el comando mvn clean install para asegurarse de que se genere.

Construyamos la imagen usando este Dockerfile. Para hacerlo, vaya al directorio raíz de la aplicación y ejecute este comando:

1
$ docker build -t greeting-app .

Docker build 1{.img-responsive}

Construimos la imagen usando docker build. Le dimos un nombre con el indicador -t y especificamos el directorio actual donde está el Dockerfile. La imagen se construye y almacena en nuestro registro docker local.

Veamos nuestra imagen:

1
$ docker images

Docker images 1{.img-responsive}

Y finalmente, ejecutemos nuestra imagen:

1
$ docker run -p 8090:8080 greeting-app 

Docker run 1{.img-responsive}

Podemos ejecutar imágenes de Docker usando el comando docker run.

Sabemos que cada contenedor es un entorno aislado en sí mismo y tenemos que mapear el puerto del sistema operativo anfitrión - 8090 y el puerto dentro del contenedor - 8080, que se especifica como -p 8090:8080 argumento.

Ahora, podemos acceder al punto final en http://localhost:8080/greet/john:

REST response 2{.img-responsive}

¡Nuestra aplicación Spring Boot se ejecuta correctamente dentro de un contenedor Docker!

Dockerización usando Maven

En la sección anterior, escribimos un Dockerfile simple y construimos nuestra aplicación usando el comando nativo docker build. Sin embargo, hay un par de problemas que podemos encontrar en nuestros proyectos usando este método:

  • El nombre .jar - Tenemos que mencionar el nombre del jar (junto con la versión) en el archivo. A medida que nuestra aplicación crezca, nuestras versiones cambiarán y también tenemos que actualizar este Dockerfile una y otra vez.
  • Usando la terminal - Tenemos que abrir manualmente una terminal y ejecutar los comandos de Docker. Sería bueno si pudiéramos hacerlo parte del ciclo de vida de Maven para que podamos crear imágenes como parte de nuestras canalizaciones de CI/CD (Integración continua/Entrega continua).

Hay muchos complementos de Maven disponibles que podemos usar en nuestro archivo pom.xml que nos facilitarían mucho la vida. La forma en que funciona este complemento de Maven es que crea internamente el Dockerfile basado en la configuración en el archivo pom.xml y luego usa el Dockerfile generado para construir la imagen.

Con este método, no es necesario que actualicemos manualmente el nombre ni ejecutemos el terminal.

Usaremos el fabric8io/docker-maven-complemento.

El complemento debe ubicarse en nuestro archivo pom.xml después de la etiqueta build. Este será un complemento de compilación opcional que utiliza perfiles de Maven. Siempre es una buena idea usar esto a través de perfiles porque queremos que el comando mvn clean install normal funcione en la máquina de un desarrollador, que tampoco tiene Docker instalado:

 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
<profiles>
   <profile>
      <activation>
         <property>
            <name>docker</name>
         </property>
      </activation>
      <build>
         <plugins>
            <plugin>
               <groupId>io.fabric8</groupId>
               <artifactId>docker-maven-plugin</artifactId>
               <version>0.26.0</version>
               <extensions>true</extensions>
               <configuration>
                  <verbose>true</verbose>
                  <images>
                     <image>
                        <name>${project.artifactId}</name>
                        <build>
                           <from>java:8-jdk-alpine</from>
                           <entryPoint>
                              <exec>
                                 <args>java</args>
                                 <args>-jar</args>
                                 <args>/maven/${project.artifactId}-${project.version}.jar</args>
                              </exec>
                           </entryPoint>
                           <assembly>
                              <descriptorRef>artifact</descriptorRef>
                           </assembly>
                        </build>
                     </image>
                  </images>
               </configuration>
               <executions>
                  <execution>
                     <id>build</id>
                     <phase>post-integration-test</phase>
                     <goals>
                        <goal>build</goal>
                     </goals>
                  </execution>
               </executions>
            </plugin>
         </plugins>
      </build>
   </profile>
</profiles>

Echemos un vistazo más de cerca a esto:

  • Nuestro perfil se llama docker - Si tenemos que construir la imagen usando Maven, debemos ejecutar el comando con -Ddocker.
  • La etiqueta <name> - Esta etiqueta especifica el nombre de la imagen, que es artifactId; en nuestro caso, es demo-docker.
  • La etiqueta <from> - Esta etiqueta especifica la imagen base de java:8-jdk-alpine.
  • La etiqueta <args>: esta etiqueta se usa para especificar cómo debe ejecutarse la imagen.

Ahora construyamos la imagen:

1
$ mvn clean install -Ddocker 

Docker build 2{.img-responsive}

Veamos nuestra imagen:

1
$ docker images

Docker images 2{.img-responsive}

Finalmente, ejecutaremos nuestra imagen:

1
$ docker run -p 8090:8080 demo-docker 

Ahora verifique el punto final REST (http://localhost:8090/saludo/john) en el navegador.

Nota: Debe detener los contenedores que se estaban ejecutando anteriormente y que usan el puerto 8090, o de lo contrario obtendrá un error.

Puede verificar fácilmente qué contenedores se están ejecutando usando:

1
$ docker ps 

Ahora, si el puerto ya está en uso, puede cambiar el puerto o eliminar el contenedor anterior usando:

1
$ docker rm -f <container-id>

Otra manera fácil es detener todos los contenedores:

1
 $ docker rm -f $(docker ps -a -q) 

Conclusión

En este artículo, cubrimos las dos formas más utilizadas de contener una aplicación Spring Boot usando Docker.

El primer enfoque se realizó mediante el uso de un Dockerfile simple para crear la imagen, y el segundo enfoque utiliza un complemento de Maven.

Una vez creada la imagen, hay muchas formas de ejecutarla. En este artículo, confiamos en el comando nativo docker run. Una forma más accesible es usar docker-compose si tiene muchas imágenes que necesita ejecutar.

Para un entorno de producción, generalmente optamos por [Kubernetes] (https://kubernetes.io/) o [Docker-enjambre] (https://docs.docker.com/engine/swarm/) para escalar nuestra aplicación basada en el tráfico de la red automáticamente. mente.