Posterior a de una extensa compilación de información pudimos solucionar este disgusto que pueden tener ciertos los lectores. Te compartimos la solución y nuestro objetivo es serte de gran ayuda.
Solución:
Estoy realmente confundido acerca del tamaño de su imagen. ¡Tengo aplicaciones Spring Boot típicas que ofrecen un servicio REST que incluye un contenedor de servlet integrado en menos de 200 MB! Parece que las dependencias de su proyecto pueden y deben optimizarse.
Imagen acoplable
El openjdk:8
(243 MB comprimido) se puede reemplazar por uno con una imagen reducida de Alpine Unix como openjdk:8-jdk-alpine
(52 MB) como imagen base, pero si no necesita capacidades de compilación (por ejemplo, no use JSP), también puede optar por openjdk:8-jre-alpine
(42 MB), que incluye solo el tiempo de ejecución, eche un vistazo a Docker Hub. Lo uso para los servicios REST basados en Spring Boot que funcionan muy bien.
Dependencias de Java
Se deben incluir las dependencias de Java necesarias para la compilación y el tiempo de ejecución, pero es posible que se incluyan dependencias no utilizadas:
- verifique sus dependencias, si las dependencias actuales de compilación/tiempo de ejecución realmente se usan o tal vez se pueden eliminar o mover para probar, consulte Gradle Java Plugin
- algunas dependencias tienen muchas dependencias transitivas (mostrar usando
gradle dependencies
), verifique los innecesarios y exclúyalos si no se usan, consulte Administración de dependencias de Gradle. ¡Asegúrese de hacer pruebas de integración antes de aplicar finalmente, algunas dependencias transitivas no están bien documentadas pero pueden ser esenciales!
Con Docker 17.05+ puede usar compilaciones de varias etapas.
“Con las compilaciones de varias etapas, usa varias declaraciones FROM en su Dockerfile. Cada instrucción FROM puede usar una base diferente, y cada una de ellas comienza una nueva etapa de la compilación. Puede copiar artefactos de manera selectiva de una etapa a otra, dejando atrás todo lo que no quieres en la imagen final”.
Entonces su Dockerfile podría verse así:
#
# first stage (build)
#
FROM openjdk:8 as build
ADD . /usr/share/app-name-tmp
WORKDIR /usr/share/app-name-tmp
RUN ./gradlew build &&
mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar
#
# second stage. use alpine to reduce the image size
#
FROM openjdk:8-jre-alpine
WORKDIR /usr/share/app-name
COPY --from=build /usr/share/app-name/app-name.jar .
EXPOSE 8080
RUN chmod +x ./docker-entry.sh
ENTRYPOINT [ "./docker-entry.sh" ]
De esta manera, solo conserva el frasco y todos los archivos innecesarios no se incluyen en la imagen final.
Cada instrucción RUN crea una nueva capa sobre el sistema de archivos existente. Entonces, la nueva capa después de la instrucción RUN que te elimina app-name-tmp
El directorio simplemente enmascara la capa anterior que contiene las bibliotecas descargadas. Por lo tanto, su imagen acoplable todavía tiene ese tamaño de todas las capas construidas.
Retire el separado RUN rm -rf /usr/share/app-name-tmp
e inclúyalo en la misma instrucción RUN que hace gradle build como se muestra a continuación.
RUN ./gradlew build
mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar
rm -rf /usr/share/app-name-tmp/*
Entonces, su Dockerfile final sería
FROM openjdk:8
ADD . /usr/share/app-name-tmp
WORKDIR /usr/share/app-name-tmp
RUN ./gradlew build
mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar
rm -rf /usr/share/app-name-tmp/*
WORKDIR /usr/share/app-name
EXPOSE 8080
RUN chmod +x ./docker-entry.sh
ENTRYPOINT [ "./docker-entry.sh" ]
La imagen creada seguirá sumando tamaño desde el directorio /usr/share/app-name-tmp.