SpringBoot+Docker:高效容器化的最佳實踐

首先為什么要使用 Docker?

Docker 是一個強大的工具,它允許開發者將他們的應用程序打包到容器中,以便可以在任何平臺上輕松部署和運行。當涉及到對 Spring Boot 應用程序進行 Docker 化時,每個開發人員都應該遵循一些最佳實踐,以確保應用程序平穩高效地運行。

在本文中,我們將探討這些最佳實踐,并提供代碼示例和說明,以幫助您對 Spring Boot 應用程序進行 Docker 化。

作為一個 java 開發者,有很多用于支持 spring-boot 應用程序的基礎官方鏡像,我們需要關注鏡像的大小,特別是當項目變大時。

使用正確的基礎鏡像

當對 Spring Boot 應用程序進行 Docker 化時,為您的應用程序選擇正確的基礎鏡像非常重要。您可能知道 Docker 中的所有鏡像都有 Linux 內核的基礎層,因此我們不需要將這部分添加到我們的鏡像中,因為我們的基礎鏡像提供了您的應用程序所需的底層內核和依賴項。選擇正確的基礎鏡像有助于確保您的應用程序在 Docker 容器中平穩高效地運行。

對于 Spring Boot 應用程序,建議使用 OpenJDK 基礎映像。OpenJDK 是 Java 開發工具包 (JDK) 的開源實現,提供 Java 運行時環境和 Java 開發工具。OpenJDK 基礎映像有不同版本,例如 Java 8、Java 11 和 Java 16。以下是使用 OpenJDK 11 基礎映像的 Dockerfile 示例:

FROM openjdk:17-jdk-slim
COPY target/springBootDockerized-0.0.1-SNAPSHOT.jar springBootDockerized-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java" , "-jar" , "/springBootDockerized-0.0.1-SNAPSHOT.jar"]

但非常重要的是,我們不需要 JDK,我們只需要 JRE java 運行時環境 我建議在 OpenJDK 官方鏈接中使用 JRE 層,您可以找到以下內容:

eclipse-temurin

作為示例 spring-boot 應用程序,添加一個 Dockerfile 到 root,如下所示:

#dockerized 使用 JDK 的不好做法
#FROM openjdk:17-jdk-slim
#COPY target/springBootDockerized-0.0.1-SNAPSHOT.jar springBootDockerized-0.0.1-SNAPSHOT.jar
#ENTRYPOINT ["java" , "-jar" , "/springBootDockerized-0.0.1-SNAPSHOT.jar"]FROM eclipse-temurin:17.0.5_8-jre-focal as builder
WORKDIR extracted
ADD ./target/*.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extractFROM eclipse-temurin:17.0.5_8-jre-focal
WORKDIR application
COPY --from=builder extracted/dependencies/ ./
COPY --from=builder extracted/spring-boot-looder/ ./
COPY --from=builder extracted/snapshot-dependencies/ ./
COPY --from=builder extracted/application/ ./EXPOSE 8085#在 springboot 3.2 之前使用它
#ENTRYPOINT ["java" , "org.springframework.boot.loader.JarLauncher"]
#在 springboot 3.2 之后使用它ENTRYPOINT ["java" , "org.springframework.boot.loader.launch.JarLauncher"]

在此示例中,第一階段使用 Maven 基礎映像來構建 Spring Boot 應用程序并生成 jar 文件。第二階段使用 OpenJDK slim 基礎鏡像,它是基礎鏡像的較小版本,僅包含 Java 運行時環境。

COPY --from=build指令將 jar 文件從第一階段復制到第二階段,該ENTRYPOINT指令指定容器啟動時應該運行的命令。

第一部分指令的含義:

  • java: 這是運行 Java 應用程序或執行 Java 字節碼的命令。

  • -Djarmode=layertools: 這是一個系統屬性,它使用 - D 標志指定。它將 HRIMARMODE 屬性的值設置為更高級的 LayerTools。這是啟用 “layertools” 模式來操作模塊化 JAR 文件中的 “層” 的另一種方法。

  • -jar app.jar: 指定要執行的 JAR 文件名為 “app.jar”。該-jar選項指示指定的文件是可執行的 JAR 文件。

  • extract: 這是在 JAR 文件中傳遞給應用程序的參數或命令。它指示應用程序執行特定操作,在本例中是提取 JAR 文件的內容。

通過這種方式使用多階段構建,我們可以創建一個精簡的 Docker 映像,其中僅包含運行 Spring Boot 應用程序所需的依賴項和文件。通過這樣做,我們可以減小圖像的大小并提高應用程序的性能。

另一種方法是使用 Build-pack.io,它會在您的 pom 中自動為您生成圖像,并將其添加到插件標簽中:

<build><plugins><plugin><configuration><image><name>kia/test</name></image></configuration><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>   

之后運行此命令:

mvn?spring-boot:build-image

使用這個命令 spring boot 可以完美地為你制作鏡像。

使用環境變量

當對 Spring Boot 應用程序進行 Docker 化時,使用環境變量來配置應用程序非常重要。使用環境變量允許您更改應用程序的配置,而無需重建 Docker 映像。

Spring Boot 應用程序可以使用application.propertiesapplication.yml文件來指定配置屬性。這些屬性可以在運行時使用環境變量覆蓋,Spring Boot 會自動將其映射到屬性。下面是一個示例 Dockerfile,它設置一個環境變量來配置 Spring Boot 應用程序的活動配置文件:

FROM openjdk:11
ENV SPRING_PROFILES_ACTIVE=production
COPY target/my-application.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

在本例中,我們將SPRING_PROFILES_ACTIVE環境變量設置為生產環境變量,這將激活 Spring Boot 應用程序中的生產配置文件。

當容器啟動時,ENTRYPOINT指令中指定的 java 命令將與-jar選項一起運行,以啟動 Spring Boot 應用程序。由于我們設置了SPRING_PROFILES_ACTIVE環境變量,應用程序將自動使用生產環境。

使用健康檢查

對 Spring Boot 應用程序進行 Docker 化時,使用運行狀況檢查來監控應用程序的運行狀況并確保其正確運行非常重要。健康檢查可用于檢測應用程序何時不健康,并根據應用程序的健康狀況自動執行恢復或擴展。

要在 Docker 映像中添加健康檢查,您可以使用 Dockerfile 中的HEALTHCHECK指令。HEALTHCHECK指令告訴 Docker 如何檢查應用程序的運行狀況。下面是一個示例 Dockerfile,它為 Spring Boot 應用程序添加了健康檢查:

FROM openjdk:11
COPY target/my-application.jar app.jar
HEALTHCHECK --interval=5s \--timeout=3s \CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "/app.jar"]

在此示例中,我們使用HEALTHCHECK指令來檢查 Spring Boot 應用程序的運行狀況。該--interval選項指定運行狀況檢查的頻率,以及--timeout指定等待響應的時間。該CMD指令運行健康檢查命令,這是 curl 檢查/actuator/health應用程序端點的命令。

運行容器時,可以使用docker ps命令查看容器的健康狀態:

$ docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS          PORTS                    NAMES
e8e1a6440e5e   my-application:1.0   "java -jar /app.jar"     5 seconds ago   Up 4 seconds    0.0.0.0:8080->8080/tcp   my-application
$ docker inspect --format='{{json .State.Health}}' my-application
{"Status":"healthy","FailingStreak":0,"Log":[{"Start":"2023-03-25T09:21:08.272130387Z","End":"2023-03-25T09:21:08.310105965Z","ExitCode":0,"Output":"\n"}]}

在此示例中,該docker ps命令顯示容器已啟動并在端口 8080 上運行。該docker inspect命令顯示容器的健康狀態,當前為 healthy。如果健康檢查失敗,容器將被標記為 unhealthy,您可以使用 Docker Compose 或 Kubernetes 等工具自動恢復或擴展容器。

使用 Docker 緩存

當對 Spring Boot 應用程序進行 Docker 化時,使用 Docker 緩存來加快構建過程并減少構建新 Docker 映像所需的時間非常重要。Docker 緩存允許您重用之前構建的 Docker 鏡像層,從而避免每次構建新鏡像時都需要重建這些層。下面是一個使用 Docker 緩存來加速構建過程的 Dockerfile 示例:

FROM openjdk:11 as builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offlineCOPY src/ ./src/
RUN mvn package -DskipTestsFROM openjdk:11
COPY --from=builder /app/target/my-application.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

每一步都假設一個緩存在 Docker 注冊表層的階段,

在此示例中,我們使用多階段構建,首先在單獨的層中構建 Spring Boot 應用程序,然后將構建的 jar 文件復制到最終鏡像中。通過在構建過程中使用單獨的層,我們可以利用 Docker 緩存來避免每次構建新鏡像時重建依賴項。

  • 構建過程的第一階段使用openjdk:11基礎鏡像并復制 pom.xml 文件到容器。然后它運行mvn dependency:go-offline命令下載應用程序所需的所有依賴項。該命令確保所有必需的依賴項在本地可用,這將加快后續構建的速度。

  • 構建過程的第二階段使用openjdk:11基礎映像并將源代碼復制到容器中。然后它運行mvn package命令來構建應用程序 jar 文件。由于我們在上一階段已經下載了依賴項,因此 Docker 將使用緩存層并跳過依賴項下載步驟。

  • 最后,該COPY --from=builder指令將構建的 jar 文件從構建器階段復制到最終映像,并且該ENTRYPOINT指令指定容器啟動時應運行的命令。

使用 .dockerignore 文件

當對 Spring Boot 應用程序進行 Docker 化時,使用.dockerignore文件從 Docker 構建上下文中排除不必要的文件和目錄非常重要。通過使用.dockerignore文件,您可以排除 Docker 鏡像不需要的文件和目錄,從而減少構建上下文的大小并提高構建性能。以下是 Spring Boot 應用程序的 .dockerignore 示例文件:

# 忽略根目錄下的所有文件
*
# 包含 src 目錄
!src/
# 包含 pom.xml 文件
!pom.xml
# 排除目標目錄及其內容
target/

在此示例中,我們使用該.dockerignore文件排除根目錄 (*) 中的所有文件,除了構建 Spring Boot 應用程序所需的src/目錄和pom.xml文件。我們還排除了target/目錄,該目錄包含構建的工件,Docker 映像不需要該目錄。

通過使用.dockerignore文件,我們可以減少構建上下文的大小并提高構建性能。Docker 只會復制.dockerignore構建上下文中包含的文件和目錄,并且會忽略文件中排除的文件和目錄。

使用.dockerignore文件是對 Spring Boot 應用程序進行 Docker 化的良好實踐,因為它有助于確保盡可能高效、快速地構建 Docker 映像。

此外,使用.dockerignore文件還可以幫助提高 Docker 鏡像的安全性。通過排除不必要的文件和目錄,您可以減少 Docker 映像的攻擊面,并最大限度地降低暴露敏感信息或憑據的風險。例如,如果您在構建目錄中存儲了配置文件或憑據,則將它們排除在.dockerignore文件中將阻止它們包含在 Docker 映像中。

還值得注意的是,該.dockerignore文件遵循與.gitignore文件類似的語法,用于從 Git 存儲庫中排除文件和目錄。如果您熟悉該.gitignore文件,.dockerignore文件的使用是零學習成本。

總之,使用.dockerignore文件是 Docker 化 Spring Boot 應用程序的良好實踐。它可以幫助減少構建上下文的大小、提高構建性能并提高 Docker 映像的安全性。

使用標簽

對 Spring Boot 應用程序進行 Docker 化時,使用標簽將元數據添加到 Docker 映像非常重要。標簽是鍵值對,可以添加到 Docker 映像中以提供有關映像的附加信息,例如版本、維護者或構建日期。下面是一個示例 Dockerfile,它使用標簽將元數據添加到 Spring Boot 應用程序:

FROM openjdk:11
LABEL maintainer="John Doe <john.doe@example.com>"
LABEL version="1.0"
LABEL description="My Spring Boot application"
COPY target/my-application.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

在此示例中,我們使用LABEL指令將元數據添加到 Docker 映像。我們為鏡像的維護者、版本和描述添加了標簽。這些標簽提供有關 Docker 映像的附加信息,并幫助用戶了解映像包含的內容及其構建方式。

您可以使用docker inspect 命令查看 Docker 鏡像的標簽:

$ docker inspect my-application
[{"Id": "sha256:...","RepoTags": ["my-application:latest"],"Labels": {"maintainer": "John Doe <john.doe@example.com>","version": "1.0","description": "My Spring Boot application"},...}
]

在本例中,docker inspect命令顯示my-application Docker 鏡像的標簽。標簽提供有關鏡像的其他信息,可以幫助用戶了解鏡像是如何構建的以及如何使用它。

以這種方式使用標簽可以幫助提高 Docker 鏡像的可用性和可維護性。通過向 Docker 映像添加元數據,您可以幫助用戶了解鏡像包含的內容及其構建方式。隨著時間的推移,此信息對于調試、故障排除和維護 Docker 鏡像非常有用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697723.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697723.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697723.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編程筆記 Golang基礎 017 數據類型:字符串類型

編程筆記 Golang基礎 017 數據類型&#xff1a;字符串類型 一、字符串類型小結 在Go語言中&#xff0c;字符串&#xff08;string&#xff09;是一種基本的數據類型&#xff0c;用于表示文本數據。它是一個不可變的字符序列&#xff0c;由UTF-8編碼的字節組成&#xff0c;支持U…

深入URP之Shader篇15: Shader關鍵字和變體

之前說了很多shader關鍵字的事情&#xff0c;本篇好好說一下關鍵字和變體。 關鍵字是干什么的 我們寫shader的時候&#xff0c;經常會遇到需要處理不同的情況&#xff0c;比如是否啟用霧&#xff0c;光源是平行光還是點光源&#xff0c;是否使用法線貼圖等等。如果為每一種情…

基于springboot+vue的大創管理系統(前后端分離)

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

【selenium】執行 Javascript 腳本 滾動、元素的特殊操作等

某些特殊情況下&#xff0c;使用selenium的api無法操作頁面元素&#xff0c;點擊、滾動實現的某些功能&#xff0c;可以考慮通過執行js來完成。 為什么不用js寫自動化&#xff1f;——selenium第一版是js寫的&#xff0c;但js兼容性存在問題&#xff0c;所以引入webdriver 現在…

ad15 PCB3D模型導出到SOLIDWORKS

注意&#xff0c;工程文件目錄不能用中文&#xff0c;否則導出的文件會不存在 將這個文件直接拖到 SOLIDWORKS 中 下一步很關鍵 顯示出來了 另存為一個轉配體就可以了

12 個對開發人員有用的 Python 腳本

目錄 Create strong random passwordsExtract text from a PDFText processing with PandocManipulate audio with PydubFilter textLocate addressesConvert a CSV to ExcelPattern match with regular expressionsConvert images to JPGCompress imagesGet content from Wiki…

FPS游戲之漫談網絡抖動引發客戶端的卡頓優化

話說各位大神 你們遇到過因為網絡抖動導致客戶端的卡頓現象嗎&#xff0c;或者說測試反饋模擬弱網環境的時候某個功能點會卡頓一下&#xff0c;然后通過各種定位&#xff0c;發現原來是一次性下發了好多包&#xff1f;&#xff1f;&#xff1f;&#xff1f; 問題來了如果我們在…

海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(14)

自己挖了一個坑,準備做SS928/SD3403的Yolov8的移植,主要是后臺私信太多人在問相關的問題。先別著急去寫代碼,因為在hi3516dv500下的移植還是比較順利。之前在hi3519av100和hi3559av100系列時遇到過一些問題,所以沒有繼續去移植新的算法。 SS928架構乍一看和hi3559av100特別…

Ubuntu系統本地部署Inis博客結合內網穿透實現遠程訪問本地站點

文章目錄 前言1. Inis博客網站搭建1.1. Inis博客網站下載和安裝1.2 Inis博客網站測試1.3 cpolar的安裝和注冊 2. 本地網頁發布2.1 Cpolar臨時數據隧道2.2 Cpolar穩定隧道&#xff08;云端設置&#xff09;2.3.Cpolar穩定隧道&#xff08;本地設置&#xff09; 3. 公網訪問測試總…

git 使用總結

文章目錄 git merge 和 git rebasegit mergegit rebase總結 git merge 和 git rebase git merge git merge 最終效果說明&#xff1a; 假設有一個倉庫情況如下&#xff0c;現需要進行 merge&#xff1a; merge 操作流程&#xff1a; merge 的回退操作&#xff1a; git reba…

Java適配器模式 - 靈活應對不匹配的接口

Java適配器模式 - 靈活應對不匹配的接口 引言&#xff1a; 在軟件開發中&#xff0c;我們經常遇到不同系統、庫或框架之間的接口不兼容問題。為了解決這些問題&#xff0c;我們可以使用適配器模式。適配器模式是一種結構型設計模式&#xff0c;它允許不兼容的接口之間進行協作…

用Python采集動態網頁Requests就不那么好用了,試試Selenium

Requests + BeautifulSoup + 額外的庫: 對于一些簡單的動態內容,你能通過分析網絡請求來找到并直接獲取這些數據。 使用 requests 庫來發送 HTTP 請求,并使用 BeautifulSoup 來解析 HTML。 對于 AJAX 請求,你可能需要使用額外的庫(如 mitmproxy 或 BrowserMob Proxy)來…

武漢AAA企業信用等級認證

AAA企業信用等級認證 1. 什么是AAA企業信用等級認證 AAA企業信用等級認證是由國家知名的第三方機構對企業的信用狀況進行評估和認證的一種方式。它是根據企業在市場經濟中所展示出的信用水平、經營實力、企業形象等方面的表現來確定企業的信用等級&#xff0c;以此為企業提供…

在線進制轉換工具

在線進制轉換 - BTool在線工具軟件&#xff0c;為開發者提供方便。 在線進制轉換器提供了二進制&#xff0c;八進制&#xff0c;十進制&#xff0c;十六進制等相互轉換功能。

Putty中運行matlab文件

首先使用命令 cd /home/ya/CodeTest/Matlab進入路徑&#xff1a;到Matlab文件夾下 然后鍵入matlab&#xff0c;進入matlab環境&#xff0c;如果main.m文件在Matlab文件夾下&#xff0c;直接鍵入main即可運行該文件。細節代碼如下&#xff1a; Unable to use key file "y…

LeetCode 2828.判別首字母縮略詞

給你一個字符串數組 words 和一個字符串 s &#xff0c;請你判斷 s 是不是 words 的 首字母縮略詞 。 如果可以按順序串聯 words 中每個字符串的第一個字符形成字符串 s &#xff0c;則認為 s 是 words 的首字母縮略詞。例如&#xff0c;“ab” 可以由 [“apple”, “banana”…

【OpenAI官方課程】第三課:ChatGPT文本總結Summarizing

歡迎來到ChatGPT 開發人員提示工程課程&#xff08;ChatGPT Prompt Engineering for Developers&#xff09;&#xff01;本課程將教您如何通過OpenAI API有效地利用大型語言模型&#xff08;LLM&#xff09;來創建強大的應用程序。 本課程由OpenAI 的Isa Fulford和 DeepLearn…

【數據分析——Python Pandas庫——數據清洗——電商數據分析】

引言 現如今&#xff0c;我們在電商平臺上購物已經成為日常生活的一部分。對于電商公司而言&#xff0c;如何準確理解消費者的需求&#xff0c;提供更好的服務是非常重要的。在這里&#xff0c;數據分析成為提供關鍵洞察力的工具。Python語言與其數據處理庫Pandas&#xff0c;…

K8S部署Java項目 pod報錯 logs日志內容:no main manifest attribute, in app.jar

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

hash,以及數據結構——map容器

1.hash是什么&#xff1f; 定義&#xff1a;hash,一般翻譯做散列、雜湊&#xff0c;或音譯為哈希&#xff0c;是把任意長度的輸入&#xff08;又叫做預映射pre-image&#xff09;通過散列算法變換成固定長度的輸出&#xff0c; 該輸出就是散列值。這種轉換是一種壓縮映射&…