Ha creado una aplicación Spring Boot. Está funcionando muy bien en su máquina local y ahora necesita implementar la aplicación en otro lugar. En algunas plataformas, puede enviar directamente el archivo jar y se implementará. En algunos lugares, puede activar una máquina virtual, descargar el código fuente allí, compilarla y ejecutarla. Pero la mayoría de las veces necesitarás implementar la aplicación mediante contenedores. La mayoría de las veces, Docker se utiliza para crear y ejecutar la imagen en un contenedor. Además, cuando carga el archivo jar en algunas plataformas, la aplicación se ejecuta dentro de un contenedor oculto.
Entonces, en este blog, veremos 3 formas diferentes de crear una imagen de Docker para la aplicación Spring Boot determinada. Empecemos:
La forma ingenua e insuficiente de crear la imagen de Docker para cualquier aplicación es usar un Dockerfile simple que copia el archivo jar dentro de la imagen y lo ejecuta usando el comando java -jar.
Aquí está el Dockerfile que puedes colocar en la raíz del proyecto:
FROM eclipse-temurin:21-jre-ubi9-minimal ARG JAR_FILE COPY ${JAR_FILE} application.jar ENTRYPOINT ["java", "-jar", "/application.jar"]
Hemos especificado un argumento JAR_FILE que es la ubicación del archivo jar a utilizar.
Después de crear el Dockerfile anterior, se siguen los siguientes pasos para crear la imagen de Docker:
Compile el archivo jar para el proyecto Spring Boot:
./gradlew bootJar # For Gradle build system
O
./mvnw spring-boot:build-jar # For Maven build system
Utilice Dockerfile para crear la imagen de Docker utilizando el archivo jar más reciente. En el siguiente comando, reemplace {IMAGE_NAME} con el nombre de la imagen requerida y {JAR_FILE} con la ruta al archivo jar generado. El nombre de la imagen también contiene una etiqueta, como - miempresa/servicio-producto:0.0.1-SNAPSHOT:
docker build --build-arg JAR_FILE={JAR_FILE} --tag {IMAGE_NAME} .
Verifique si la imagen de Docker está creada usando el siguiente comando. Debería poder ver la imagen con el nombre especificado en el comando anterior:
docker images
Si bien es posible y fácil empaquetar un uber jar de Spring Boot como una imagen de Docker (como se mencionó en el método anterior), existen muchas desventajas al copiar y ejecutar el fat jar tal como está en la imagen de Docker. Por ejemplo,
Dado que compilamos nuestro código con más frecuencia que actualizamos la versión Spring Boot, es mejor separar las cosas un poco más. Si colocamos esos archivos jar (que rara vez se modifican) en la capa anterior a la capa de aplicación, entonces Docker a menudo necesita cambiar solo la capa inferior y puede seleccionar el resto de su caché.
Para crear una imagen Docker en capas, primero debemos crear un jar en capas. Hoy en día, está habilitado de forma predeterminada en Gradle y Maven. Puede habilitar o deshabilitar el comportamiento del frasco en capas usando la siguiente configuración:
// build.gradle tasks.named("bootJar") { layered { enabled = false } }
// build.gradle.kts tasks.named("bootJar") { layered { enabled.set(false) } }
org.springframework.boot spring-boot-maven-plugin true
Incluso puedes ajustar cómo se crean las capas. Consulte la documentación para la configuración de gradle o maven.
A continuación se muestra el Dockerfile, que se puede utilizar para aprovechar el jar en capas y crear una imagen Docker en capas de la aplicación Spring Boot.
# Perform the extraction in a separate builder container FROM eclipse-temurin:21-jre-ubi9-minimal AS builder WORKDIR /builder # This points to the built jar file in the target folder # Adjust this to 'build/libs/*.jar' if you're using Gradle ARG JAR_FILE=target/*.jar # Copy the jar file to the working directory and rename it to application.jar COPY ${JAR_FILE} application.jar # Extract the jar file using an efficient layout RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted # This is the runtime container FROM eclipse-temurin:21-jre-ubi9-minimal WORKDIR /application # Copy the extracted jar contents from the builder container into the working directory in the runtime container # Every copy step creates a new docker layer # This allows docker to only pull the changes it really needs COPY --from=builder /builder/extracted/dependencies/ ./ COPY --from=builder /builder/extracted/spring-boot-loader/ ./ COPY --from=builder /builder/extracted/snapshot-dependencies/ ./ COPY --from=builder /builder/extracted/application/ ./ # Start the application jar - this is not the uber jar used by the builder # This jar only contains application code and references to the extracted jar files # This layout is efficient to start up and CDS friendly ENTRYPOINT ["java", "-jar", "application.jar"]
Los pasos para crear la imagen de Docker en capas son los mismos que para crear una imagen de Docker básica. Consulte allí.
¿Qué pasa si te digo que puedes crear una imagen de Docker sin crear un Dockerfile? Podemos crear imágenes de Docker directamente desde el complemento Gralde o Maven utilizando Cloud Native Buildpacks. Algunas plataformas (como Heroku o Cloud Foundry) usan Buildpacks para convertir archivos jar proporcionados en imágenes ejecutables.
Spring Boot incluye compatibilidad con paquetes de compilación directamente para Maven y Gradle. No necesitamos incluir ningún complemento adicional. Simplemente ejecute el siguiente comando:
./gradlew bootBuildImage # For gradle build system
O
./mvnw spring-boot:build-image # For maven build system
El comando anterior genera una imagen con el nombre predeterminado {PROJECT_NAME}:${PROJECT_VERSION}. Si desea configurar el nombre de la imagen generada, puede seguir los siguientes pasos:
Podemos configurar la tarea bootBuildImage para establecer el nombre de la imagen, así:
// For build.gradle.kts val imagePrefix = "javarush" val dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName.set("${imagePrefix}/${dockerImageName}:${version}") }
// For build.gradle def imagePrefix = "javarush" def dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName = "${imagePrefix}/${dockerImageName}:${version}" }
Podemos configurar spring-boot-maven-plugin para usar otro nombre de imagen, como este:
... javarush org.springframework.boot spring-boot-maven-plugin ${imagePrefix}/${project.artifactId}:${project.version}
Incluso podemos definir el nombre de la imagen mientras ejecutamos el comando para construir la imagen.
./gradlew bootBuildImage --imageName=javarush/docker-example:1.0.0 # For grade build system ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=javarush/docker-example:1.0.0 # For maven build system
Puedes ver la documentación para configurar aún más el complemento Gradle o Maven.
Este es mi método de referencia para crear una imagen de Docker para cualquier aplicación Spring Boot.
Una vez que creas una imagen de la ventana acoplable, debes asegurarte de que funcione como se esperaba. Después de asegurarse de que se haya creado la imagen, puede ejecutarla directamente usando el comando Docker Run. Por ejemplo,
docker run -p "8080:8080" {IMAGE_NAME}
Pero no es así como se utilizan las imágenes en las aplicaciones de producción. Docker Compose se utiliza para ejecutar y administrar múltiples imágenes de Docker.
En este blog, hemos visto cómo crear imágenes de Docker para aplicaciones Spring Boot utilizando diferentes métodos. Ser capaz de crear imágenes acoplables para sus aplicaciones es una habilidad imprescindible porque la imagen es lo que se entrega. Gracias por leer el artículo hasta el final. Te lo agradezco. Te veré en el próximo. Como siempre, todos los comentarios y sugerencias son bienvenidos.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3