🌱 Digital Garden

Search

Search IconIcon to open search

Deploy de una aplicacion de Spring con Docker

Last updated Aug 6, 2023 Edit Source

Para realizar el deploy de una aplicacion de Spring Core con Docker, lo primero que se necesita hacer es empaquetar la aplicacion en su respectivo .jar

1
mvn clean package

Una vez la tenemos lista, podemos proceder a crear una imagen de Docker.

Para crear la imagen hay dos formas.

  1. Utilizar una imagen base que ya existe en Docker o en cualquier otro repositorio
  2. Utilizar una nueva imagen desde cero, desde un docker file herdando de una imagen de Docker hub

# Dockerfile

Para realizarlo a partir de un Dockerfile, lo primero que se debe hacer es identificar en Docker Hub la version del openjdk a utilizar.

Una vez identificada, podemos empezar a construir nuestro dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
FROM openjdk:17.0.3
# Heredamos a partir de la imagen openjdk version 17.0.3

# Establecemos el directorio de trabajo actual en /app
WORKDIR /app 

# Copiamos el archivo .jar al directorio actual (/app)
COPY ./path/to/app-version.jar .

# Documentamos el puerto que va a utilizar la aplicacion
EXPOSE 8080

# Establecemos los comandos de entrada a ejecutar para lanzar la aplicacion
ENTRYPOINT ["java", "-jar", "app-version.jar"]

# Docker build

Una vez escrita el dockerfile para la aplicacion, se debe construir la imagen a partir de ella. Para esto, nos dirigimos a la carpeta que contiene ahora le Dockerfile y lo construimos utilizando:

1
docker build -t <tag> .

Una vez finalizada, la imagen habra sido construida y podra ser visualizada junto con todas las demas usando:

1
docker images

Y finalmente puede ser levantada utilizando su identificador (o tag) y mapeando un puerto externo con el interno del contenedor.

1
docker run -p 8080:8080 <image_ID>

# Optimizaciones

Podemos hacer que el Dockerfile no solo se encarge de crear el imagen obteniendo ya un jar, si no que tambien, se encargue de compilar el codigo fuente y descargar las dependencias necesarias. Para realizar estas operaciones desde el dockerfile correctamente es improtante saber que este trabaja en forma de cascada por capas, si se modifica una capa superior todas las capas subsecuentas van a tener que realizarse otra vez.

# Dependencias

Conociendo esto podemos hacer un Dockerfile de tal forma que cambios en el codigo fuente no afecten la descarga de las dependencias:

 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
FROM openjdk:17.0.3
# Heredamos a partir de la imagen openjdk version 17.0.3

# Establecemos el directorio de trabajo actual en /app/users-microservice
WORKDIR /app/users-microservice

# Copiamos todos los archivos necesarios para que maven pueda descargar las edpendencias
COPY ./pom.xml /app
COPY ./users-microservice/.mvn ./.mvn
COPY ./users-microservice/mvnw .
COPY ./users-microservice/pom.xml .

# Descargamos las dependencias saltandonos todo lo relacionado con el codigo fuente, debido aque este no existe dentro del contenedo raun
RUN ./mvnw clean package -Dmaven.test.skip -Dmaven.main.skip -Dspring-boot.repackage.skip && rm -r ./target/

# Alternativa en caos ed que los paquetes cambien
#RUN ./mvnw dependency:go-offline

# Copiamos el codigo fuente
COPY ./users-microservice/src ./src/

# Compilamos de forma final con maven el codigo fuente
RUN ./mvnw clean package -DskipTests

# Documentamos el puerto que va a utilizar la aplicacion
EXPOSE 8080

# Establecemos los comandos de entrada a ejecutar para lanzar la aplicacion
ENTRYPOINT ["java", "-jar", "app-version.jar"]

# Peso

Para optimizar el peso, se utiliza una especie de implementacion del patron builder para construir la imagen de Docker en multietapas.

# Errores comunes

# La conexion a la base de datos es invalida

Esto se causa debido a que, dentro del container, su localhost es completamente diferente al localhost que se tenia cuando se corria la aplicacion en local, para corregirlo, se puede reemplazar el “localhost” dentro de las configuraciones del aplicacion.properties a host.docker.internal.

1
spring.datasource.url=jdbc:mysql://host.docker.internal:3306/<database_name>

Posterior a este cambio, se debe de regenerar el jar y el contenedor desde cero.