觀察:Spring Boot with Docker

2022-12-23 17:19:01 來源:51CTO博客

本指南將引導您完成構建碼頭工人?用于運行 Spring 引導應用程序的映像。我們從一個基本開始,并進行一些調整。然后我們展示了幾個使用構建插件(用于 Maven 和 Gradle)而不是 .這是一個“入門”指南,因此范圍僅限于一些基本需求。如果要構建用于生產用途的容器映像,則需要考慮許多事項,并且不可能在簡短指南中涵蓋所有事項。??Dockerfile????docker??

還有一個關于 Docker 的主題指南,它涵蓋了我們在這里擁有的更廣泛的選擇,并且更詳細。


(資料圖片)

您將構建什么

碼頭工人是一個具有“社交”方面的 Linux 容器管理工具包,允許用戶發布容器鏡像并使用其他人發布的容器鏡像。Docker 映像是運行容器化進程的方法。在本指南中,我們為一個簡單的 Spring 引導應用程序構建了一個。

你需要什么

約15分鐘最喜歡的文本編輯器或 IDEJDK 1.8或以后格拉德爾 4+或梅文 3.2+您也可以將代碼直接導入到 IDE 中:彈簧工具套件 (STS)智能理念VSCode

如果您不使用 Linux 機器,則需要一臺虛擬化服務器。如果您安裝了VirtualBox,則Mac等其他工具可以為您無縫管理它。訪問??boot2docker??VirtualBox的下載網站,然后選擇適合您機器的版本。下載并安裝。不要擔心實際運行它。

您還需要碼頭工人,僅在 64 位計算機上運行。看https://docs.docker.com/installation/#installation了解有關為您的計算機設置 Docker 的詳細信息。在繼續操作之前,請驗證是否可以從 shell 運行命令。如果使用 ,則需要運行它。??docker????boot2docker??

從 Spring 初始化開始

你可以使用這個預初始化項目,然后單擊生成以下載 ZIP 文件。此項目配置為適合本教程中的示例。

手動初始化項目:

導航到https://start.spring.io.此服務拉入應用程序所需的所有依賴項,并為您完成大部分設置。選擇 Gradle 或 Maven 以及您要使用的語言。本指南假定您選擇了 Java。單擊“依賴關系”,然后選擇“Spring Web”。單擊生成。下載生成的 ZIP 文件,該文件是配置了您選擇的 Web 應用程序的存檔。

如果您的 IDE 集成了 Spring Initializr,則可以從 IDE 完成此過程。

您也可以從 Github 分叉項目,然后在 IDE 或其他編輯器中打開它。

設置 Spring 引導應用程序

現在,您可以創建一個簡單的應用程序:

??src/main/java/hello/Application.java??

package hello;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublic class Application {  @RequestMapping("/")  public String home() {    return "Hello Docker World";  }  public static void main(String[] args) {    SpringApplication.run(Application.class, args);  }}

該類被標記為 a 和 a ,這意味著它已準備好供 Spring MVC 用于處理 Web 請求。 映射到發送響應的方法。該方法使用 Spring Boot 的方法啟動應用程序。??@SpringBootApplication????@RestController????@RequestMapping????/????home()????Hello World????main()????SpringApplication.run()??

現在我們可以在沒有 Docker 容器的情況下運行應用程序(即在主機操作系統中):

如果您使用 Gradle,請運行以下命令:

./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar

如果使用 Maven,請運行以下命令:

./mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar

然后轉到??本地主機:8080??以查看您的“Hello Docker World”消息。

容器化

Docker有一個簡單的“Dockerfile”用于指定圖像“圖層”的文件格式。在 Spring 引導項目中創建以下 Dockerfile:

例 1.Dockerfile

FROM openjdk:8-jdk-alpineARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarENTRYPOINT ["java","-jar","/app.jar"]

如果您使用 Gradle,則可以使用以下命令運行它:

docker build --build-arg JAR_FILE=build/libs/\*.jar -t springio/gs-spring-boot-docker .

如果使用 Maven,則可以使用以下命令運行它:

docker build -t springio/gs-spring-boot-docker .

此命令將生成映像并將其標記為 。??springio/gs-spring-boot-docker??

這個 Dockerfile 非常簡單,但它是運行 Spring Boot 應用程序所需要的一切,沒有任何多余的裝飾:只有 Java 和一個 JAR 文件。該構建將創建一個 spring 用戶和一個 spring 組來運行應用程序。然后(通過命令)將項目 JAR 文件復制到容器中,作為 ,在 中運行。使用 Dockerfile 的數組形式,以便沒有 shell 包裝 Java 進程。這??COPY????app.jar????ENTRYPOINT????ENTRYPOINT??關于 Docker 的主題指南將更詳細地討論此主題。

要減少雄貓啟動時間?,我們曾經添加一個指向熵源的系統屬性。這不再是必需的??/dev/urandom??JDK 8 或更高版本.

使用用戶權限運行應用程序有助于降低某些風險(例如,請參閱:堆棧交換上的一個線程).因此,對 的一個重要改進是以非 root 用戶身份運行應用程序:??Dockerfile??

例 2.Dockerfile

FROM openjdk:8-jdk-alpineRUN addgroup -S spring && adduser -S spring -G springUSER spring:springARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarENTRYPOINT ["java","-jar","/app.jar"]

生成并運行應用程序時,可以在應用程序啟動日志中看到用戶名:

docker build -t springio/gs-spring-boot-docker .docker run -p 8080:8080 springio/gs-spring-boot-docker

請注意第一個日志條目中的:??started by????INFO??

:: Spring Boot ::        (v2.2.1.RELEASE)2020-04-23 07:29:41.729  INFO 1 --- [           main] hello.Application                        : Starting Application on b94c86e91cf9 with PID 1 (/app started by spring in /)...

此外,在 Spring Boot 胖 JAR 文件中,依賴項和應用程序資源之間存在清晰的分離,我們可以利用這一事實來提高性能。關鍵是在容器文件系統中創建層。這些層在構建時和運行時(在大多數運行時)都緩存,因此我們希望將最頻繁更改的資源(通常是應用程序本身中的類和靜態資源)分層在變化較慢的資源之后。因此,我們使用稍微不同的 Dockerfile 實現:

例 3.Dockerfile

FROM openjdk:8-jdk-alpineRUN addgroup -S spring && adduser -S spring -G springUSER spring:springARG DEPENDENCY=target/dependencyCOPY ${DEPENDENCY}/BOOT-INF/lib /app/libCOPY ${DEPENDENCY}/META-INF /app/META-INFCOPY ${DEPENDENCY}/BOOT-INF/classes /appENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

這個 Dockerfile 有一個參數,指向我們解壓縮胖 JAR 的目錄。要將參數與 Gradle 一起使用,請運行以下命令:??DEPENDENCY????DEPENDENCY??

mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar)

要將參數與 Maven 一起使用,請運行以下命令:??DEPENDENCY??

mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

如果我們做對了,它已經包含一個包含依賴 JAR 的目錄,以及一個包含應用程序類的目錄。請注意,我們使用應用程序自己的主類:。(這比使用胖 JAR 啟動器提供的間接尋址更快。??BOOT-INF/lib????BOOT-INF/classes????hello.Application??

分解 JAR 文件可能導致類路徑順序為運行時不同.一個行為良好且編寫良好的應用程序不應該關心這一點,但如果依賴項沒有得到仔細管理,您可能會看到行為變化。

如果使用 ,則需要運行它,然后再使用 Docker 命令行或構建工具執行任何操作(它運行一個守護進程,在虛擬機中為您處理工作)。??boot2docker??

在 Gradle 構建中,您需要在 Docker 命令行中添加顯式構建參數:

docker build --build-arg DEPENDENCY=build/dependency -t springio/gs-spring-boot-docker .

要在 Maven 中構建映像,可以使用更簡單的 Docker 命令行:

docker build -t springio/gs-spring-boot-docker .

當然,如果您只使用 Gradle,則可以更改默認值 使默認值 與解壓縮存檔的位置相匹配。??Dockerfile????DEPENDENCY??

您可能希望使用構建插件,而不是使用 Docker 命令行進行構建。Spring Boot 支持使用自己的構建插件從 Maven 或 Gradle 構建容器。谷歌也有一個名為臂有Maven和Gradle插件。這種方法最有趣的地方可能是您不需要 .您可以使用與從 獲取的相同的標準容器格式來生成映像。此外,它可以在未安裝 docker 的環境中工作(在構建服務器中并不少見)。??Dockerfile????docker build??

默認情況下,默認構建包生成的映像不會以 root 用戶身份運行應用程序。查看配置指南格拉德爾?或馬文了解如何更改默認設置。

使用 Gradle 構建 Docker 鏡像

您可以在一個命令中使用 Gradle 構建標記的 docker 映像:

./gradlew bootBuildImage --imageName=springio/gs-spring-boot-docker

使用 Maven 構建 Docker 鏡像

要快速入門,您可以運行 Spring 啟動映像生成器,甚至無需更改您的(請記住,如果仍然存在,則忽略):??pom.xml????Dockerfile??

./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=springio/gs-spring-boot-docker

要推送到 Docker 注冊表,您需要具有推送權限,默認情況下您沒有推送權限。將映像前綴更改為您自己的 Dockerhub ID,并確保在運行 Docker 之前進行身份驗證。??docker login??

推送后

示例中的 A 失敗(除非您是 Dockerhub 的“springio”組織的一部分)。但是,如果更改配置以匹配自己的 docker ID,則應該會成功。然后,您將擁有一個新的標記的已部署映像。??docker push??

您不必向 docker 注冊或發布任何內容即可運行本地構建的 docker 映像。如果你使用 Docker 構建(從命令行或從 Spring Boot),你仍然有一個本地標記的鏡像,你可以像這樣運行它:

$ docker run -p 8080:8080 -t springio/gs-spring-boot-dockerContainer memory limit unset. Configuring JVM for 1G container.Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=86381K -XX:ReservedCodeCacheSize=240M -Xss1M -Xmx450194K (Head Room: 0%, Loaded Class Count: 12837, Thread Count: 250, Total Memory: 1073741824)....2015-03-31 13:25:48.035  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)2015-03-31 13:25:48.037  INFO 1 --- [           main] hello.Application                        : Started Application in 5.613 seconds (JVM running for 7.293)

CF 內存計算器在運行時用于調整 JVM 的大小以適合容器。

然后,該應用程序可在??http://localhost:8080??(訪問它,它說,“你好碼頭工人世界”)。

將 Mac 與 boot2docker 配合使用時,您通常會在啟動時看到如下內容:

Docker client to the Docker daemon, please set:    export DOCKER_CERT_PATH=/Users/gturnquist/.boot2docker/certs/boot2docker-vm    export DOCKER_TLS_VERIFY=1    export DOCKER_HOST=tcp://192.168.59.103:2376

要查看應用程序,您必須訪問 DOCKER_HOST 中的 IP 地址而不是本地主機 — 在這種情況下,https://192.168.59.103:8080,VM 的面向公眾的 IP。

當它運行時,您可以在容器列表中看到,類似于以下示例:

$ docker psCONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS                    NAMES81c723d22865        springio/gs-spring-boot-docker:latest   "java -Djava.secur..."   34 seconds ago      Up 33 seconds       0.0.0.0:8080->8080/tcp   goofy_brown

若要再次關閉它,可以使用上一個列表中的容器 ID 運行(你的 ID 會有所不同):??docker stop??

docker stop goofy_brown81c723d22865

如果您愿意,也可以在完成容器后刪除容器(它保留在文件系統中的某個位置):??/var/lib/docker??

docker rm goofy_brown

使用彈簧輪廓

使用 Spring 配置文件運行新創建的 Docker 映像就像將環境變量傳遞給 Docker run 命令(對于配置文件)一樣簡單:??prod??

docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

您可以對配置文件執行相同的操作:??dev??

docker run -e "SPRING_PROFILES_ACTIVE=dev" -p 8080:8080 -t springio/gs-spring-boot-docker

在 Docker 容器中調試應用程序

若要調試應用程序,可以使用JPDA 運輸.我們將容器視為遠程服務器。要啟用此功能,請在變量中傳遞 Java 代理程序設置,并在容器運行期間將代理程序的端口映射到本地主機。跟JAVA_OPTS適用于 Mac 的 Docker,有一個限制,因為我們無法通過 IP 訪問容器,沒有黑魔法用法.

docker run -e "JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" -p 8080:8080 -p 5005:5005 -t springio/gs-spring-boot-docker

總結

祝賀!您已經為 Spring Boot 應用程序創建了一個 Docker 容器!默認情況下,Spring 引導應用程序在容器內的端口 8080 上運行,我們通過命令行將其映射到主機上的同一端口。??-p??

標簽: 應用程序 碼頭工人 可以使用

上一篇:天天熱消息:使用基于 Vaadin 的用戶界面在基于 Spring Data JPA 的后端
下一篇:【當前熱聞】從Spring Tool Suite(STS)將“hello world”Spring應用程序部署到Cloud Foundry的過程