Dockerfile para Imagen por capas Spring Boot

Dockerfile para Imagen por capas Spring Boot

creando Spring-Boot por capas en una imagen docker con Dockerfile

Una recomendación a la hora de realizar imagenes Docker de aplicaciones spring-boot es empaquetar la aplicación por capas.

Al crear nuestras imagenes por capas evitamos tener construciones y empaquetados pesados como lo son los jar, adiconal a esto ganamos tiempo de compilación, ya que podemos reutilizar las capas que no sufrieron cambios y usar solo las capas afectadas por nuestros cambios.

Configuración

Lo primero es incluir en el plugin spring-boot-maven-plugin la configuración de capas.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <layers>
            <enabled>true</enabled>
        </layers>
    </configuration>
</plugin>

Creando el Dockerfile

Para lograr obtener las capas de nuestra aplicación empaquetada en un jar debemos debemos ejecutar java -Djarmode=layertools -jar app.jar extract esto extraera las capas de spring boot.

Spring boot tiene la siguiente estructura para sus capas:

  • dependencies
  • spring-boot-loader
  • snapshot-dependencies
  • application

Para hacer esta extración en el Dockerfile vamos a crear una sección que denominaremos builder y en esta ejecutamos la sentencia de extracción.

# the first stage of our build will extract the layers
FROM openjdk:14-ea-jdk-alpine as builder

ARG WORKDIR_BASE=/home/application

WORKDIR $WORKDIR_BASE/bin

COPY ./target/my-app.jar app.jar

RUN java -Djarmode=layertools -jar app.jar extract

Al final de la sección vemos la sentencia escencial para extracer las capas RUN java -Djarmode=layertools -jar app.jar extract

Luego en una nueva sección vamos a generar nuestra aplicación con la configuración de variables de entorno y demas elementos que permitirán que esta funcione correctamente.

Nos quedaría algo como esto

## Builder App Image
FROM openjdk:14-ea-jdk-alpine
LABEL maintainer="Henry Martinez (hmartinez@novopayment.com)"

ARG USER_GROUP=app-group
ARG USER=app-user
ARG WORKDIR_BASE=/home/application

WORKDIR $WORKDIR_BASE/bin

RUN mkdir -p $WORKDIR_BASE/logs && addgroup $USER_GROUP && adduser \
                                         --disabled-password \
                                         --gecos "" \
                                         --ingroup $USER_GROUP \
                                         --no-create-home \
                                         $USER
EXPOSE 8080

ENV TZ="America/Bogota"

COPY --from=builder $WORKDIR_BASE/bin/dependencies ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/spring-boot-loader ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/snapshot-dependencies ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/application ./

RUN chown -R $USER:$USER_GROUP $WORKDIR_BASE

USER $USER

ENTRYPOINT java org.springframework.boot.loader.JarLauncher

De lo anterior, las lineas que debemos resaltar son las que incluyen las capas de spring boot en nuestra aplicación

COPY --from=builder $WORKDIR_BASE/bin/dependencies ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/spring-boot-loader ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/snapshot-dependencies ./
RUN true
COPY --from=builder $WORKDIR_BASE/bin/application ./

y la linea de ejecución de la aplicación ENTRYPOINT java org.springframework.boot.loader.JarLauncher

Estas dos secciones son la que nos permiten construir y ejecutar nuestra aplicacion por capas.

Ya con esto tendriamos nuestro Dockerfile finalizado para crear y ejecutar una aplicación con spring boot en capas, solo nos resta construir la imagen que se ejecuta con el comando

docker build -t my-app:latest .

my-app:latest es el nombre con el que deseamos que la imagen se cree.