Sie haben eine Spring Boot-Anwendung erstellt. Es funktioniert hervorragend auf Ihrem lokalen Computer und jetzt müssen Sie die Anwendung woanders bereitstellen. Auf einigen Plattformen können Sie die JAR-Datei direkt übermitteln und sie wird bereitgestellt. An manchen Orten können Sie eine virtuelle Maschine starten, dort den Quellcode herunterladen, ihn erstellen und ausführen. Meistens müssen Sie die Anwendung jedoch mithilfe von Containern bereitstellen. Meistens wird Docker verwendet, um das Image in einem Container zu erstellen und auszuführen. Wenn Sie die JAR-Datei auf einige Plattformen hochladen, wird die Anwendung außerdem in einem Container unter der Haube ausgeführt.
In diesem Blog werden wir drei verschiedene Möglichkeiten sehen, ein Docker-Image für die jeweilige Spring Boot-Anwendung zu erstellen. Fangen wir an:
Der naive und unzureichende Weg, das Docker-Image für jede Anwendung zu erstellen, besteht darin, eine einfache Docker-Datei zu verwenden, die die JAR-Datei in das Image kopiert und sie mit dem Befehl java -jar ausführt.
Hier ist die Docker-Datei, die Sie im Stammverzeichnis des Projekts ablegen können:
FROM eclipse-temurin:21-jre-ubi9-minimal ARG JAR_FILE COPY ${JAR_FILE} application.jar ENTRYPOINT ["java", "-jar", "/application.jar"]
Wir haben ein Argument JAR_FILE angegeben, das den Speicherort der zu verwendenden JAR-Datei angibt.
Nachdem die obige Docker-Datei erstellt wurde, werden die folgenden Schritte verwendet, um das Docker-Image zu erstellen:
Erstellen Sie die JAR-Datei für das Spring Boot-Projekt:
./gradlew bootJar # For Gradle build system
ODER
./mvnw spring-boot:build-jar # For Maven build system
Verwenden Sie die Docker-Datei, um das Docker-Image mit der neuesten JAR-Datei zu erstellen. Ersetzen Sie im folgenden Befehl {IMAGE_NAME} durch den erforderlichen Bildnamen und {JAR_FILE} durch den Pfad zur generierten JAR-Datei. Der Bildname enthält auch ein Tag, etwa – mycompany/product-service:0.0.1-SNAPSHOT:
docker build --build-arg JAR_FILE={JAR_FILE} --tag {IMAGE_NAME} .
Überprüfen Sie mit dem folgenden Befehl, ob das Docker-Image erstellt wurde. Sie sollten das Bild mit dem im obigen Befehl angegebenen Namen sehen können:
docker images
Obwohl es möglich und einfach ist, ein Spring Boot-Uber-Jar als Docker-Image zu packen (wie in der vorherigen Methode erwähnt), hat das Kopieren und Ausführen des Fat-Jars im Docker-Image viele Nachteile. Zum Beispiel
Da wir unseren Code häufiger kompilieren als die Spring Boot-Version aktualisieren, ist es besser, die Dinge etwas stärker zu trennen. Wenn wir diese JAR-Dateien (die selten geändert werden) in der Ebene vor der Anwendungsebene ablegen, muss Docker oft nur die unterste Ebene ändern und kann den Rest aus seinem Cache auswählen.
Um ein mehrschichtiges Docker-Image zu erstellen, müssen wir zuerst ein mehrschichtiges JAR erstellen. Heutzutage ist es in Gradle und Maven standardmäßig aktiviert. Sie können das mehrschichtige JAR-Verhalten mit der folgenden Einstellung aktivieren oder deaktivieren:
// build.gradle tasks.named("bootJar") { layered { enabled = false } }
// build.gradle.kts tasks.named<BootJar>("bootJar") { layered { enabled.set(false) } }
<!-- pom.xml --> <project> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layers> <enabled>true</enabled> </layers> </configuration> </plugin> </plugins> </build> </project>
Sie können sogar anpassen, wie die Ebenen erstellt werden. Informationen zur Gradle- oder Maven-Konfiguration finden Sie in der Dokumentation.
Unten finden Sie die Docker-Datei, mit der Sie die Vorteile des mehrschichtigen JAR nutzen und ein mehrschichtiges Docker-Image der Spring Boot-Anwendung erstellen können.
# 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"]
Die Schritte zum Erstellen des mehrschichtigen Docker-Images sind dieselben wie zum Erstellen eines einfachen Docker-Images. Bitte schauen Sie dort nach.
Was wäre, wenn ich Ihnen sage, dass Sie ein Docker-Image erstellen können, ohne eine Docker-Datei zu erstellen? Mit Cloud Native Buildpacks können wir Docker-Images direkt aus dem Gralde- oder Maven-Plugin erstellen. Einige Plattformen (wie Heroku oder Cloud Foundry) verwenden Buildpacks, um bereitgestellte JAR-Dateien in ausführbare Bilder zu konvertieren.
Spring Boot bietet Buildpack-Unterstützung direkt für Maven und Gradle. Wir müssen keine zusätzlichen Plugins einbinden. Führen Sie einfach den folgenden Befehl aus:
./gradlew bootBuildImage # For gradle build system
ODER
./mvnw spring-boot:build-image # For maven build system
Der obige Befehl generiert ein Bild mit dem Standardnamen {PROJECT_NAME}:${PROJECT_VERSION}. Wenn Sie den Namen des generierten Bildes konfigurieren möchten, können Sie die folgenden Schritte ausführen:
Wir können die bootBuildImage-Aufgabe so konfigurieren, dass sie den Namen des Bildes festlegt:
// For build.gradle.kts val imagePrefix = "javarush" val dockerImageName = "docker-example" tasks.named<BootBuildImage>("bootBuildImage") { imageName.set("${imagePrefix}/${dockerImageName}:${version}") }
// For build.gradle def imagePrefix = "javarush" def dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName = "${imagePrefix}/${dockerImageName}:${version}" }
Wir können das Spring-Boot-Maven-Plugin so konfigurieren, dass es einen anderen Bildnamen verwendet, etwa so:
<properties> <imagePrefix>javarush</imagePrefix> </properties> ... <project> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <name>${imagePrefix}/${project.artifactId}:${project.version}</name> </image> </configuration> </plugin> </plugins> </build> </project>
Wir können sogar den Namen des Bildes definieren, während wir den Befehl zum Erstellen des Bildes ausführen.
./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
You can see the documentation to further configure Gradle or Maven plugin.
This is my go-to method to create a Docker image for any Spring Boot application.
Once you create a docker image, you need to make sure that it works as expected. After you make sure that the image is created, you can directly run it using the docker run command. For example,
docker run -p "8080:8080" {IMAGE_NAME}
But, this is not how images are used in production applications. Docker Compose is used to run and manage multiple docker images.
In this blog, we have seen how to build Docker images for Spring Boot applications using different methods. Being able to build docker images for your apps is a must skill to know because the image is what gets delivered. Thanks for reading the article till the end. I appreciate it. I will meet you in the next one. As always, all feedback and suggestions are welcome.
Das obige ist der detaillierte Inhalt vonErstellen eines Docker-Images der Spring Boot-Anwendung mithilfe von Buildpacks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!