Spring Boot 應用的 Docker 化:從 Maven 構建到 Docker 部署的完整指南

1. 使用Dockerfile部署

# 使用Java 8基礎鏡像
FROM java:8
LABEL authors="mabh"# 設置時區為Asia/Shanghai,可以根據需要更改
ENV TIME_ZONE=Asia/Shanghai# 更新時區
RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone# 設置容器內的工作目錄
WORKDIR /app# 將構建好的Spring Boot應用jar文件復制到鏡像中
COPY ./${project.build.finalName}.jar /app/COPY ./application.yml /app/
COPY ./application-${activatedProperties}.yml /app/# 暴露端口
EXPOSE 8080# 設置Java虛擬機初始內存和最大內存
#-server: 啟用Java HotSpot虛擬機的服務器模式,該模式針對長時間運行的應用程序進行了優化以提高性能。
#-Xms512m: 設置Java堆的初始大小為512兆字節。
#-Xmx1024m: 設置Java堆的最大大小為1024兆字節。
#-XX:+UseG1GC: 啟用G1垃圾收集器。G1(Garbage-First)是一種相對新的垃圾收集器,旨在提供更可預測的停頓時間和更好的性能。
#-XX:+HeapDumpOnOutOfMemoryError: 在發生內存溢出錯誤時生成堆轉儲文件。這對于分析內存問題非常有用。
#-XX:HeapDumpPath=/dumps/oom_dump.hprof: 指定內存轉儲文件。在這個例子中,堆轉儲文件將被寫入 /dumps/oom_dump.hprof 目錄文件中。
ENV JAVA_OPTS="-server -Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps/oom_dump.hprof"ENV APP_ENV="--spring.profiles.active=${activatedProperties}"
# 創建內存轉儲文件和日志文件存儲目錄
RUN mkdir /app/dumps
RUN mkdir /app/logs# 設置容器啟動時執行的命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dlogging.file=/app/logs/application.log -jar /app/${project.build.finalName}.jar ${APP_ENV}"]

包含如下基本功能:

  1. 設置時區為Asia/Shanghai
  2. 自動獲取 maven 應用包名,不需要額外修改即可使用。
  3. 自動識別 profile 使用的配置文件 不管是 application-dev.yml 、*-test.yml *.prod.yml 都可以識別出來。
  4. 默認暴漏8080端口

以下是它的主要特點和功能:

  1. 基礎鏡像:使用了 Java 8 我自定義的鏡像,你們使用dockerhub 上的就行 的基礎鏡像,這適用于許多傳統的 Java 應用程序。
  2. 時區設置:設置時區為 Asia/Shanghai。這是一個重要的設置,特別是對于需要關注本地時間的應用程序。如果需要,可以輕松更改為其他時區。
  3. 工作目錄:在容器內設置了 /app 作為工作目錄。
  4. 文件復制:將構建的 Spring Boot 應用 jar 文件以及相關的配置文件(application.ymlapplication-${activatedProperties}.yml)復制到鏡像中,自動識別 profile 使用的配置文件 。
  5. 端口暴露:默認暴露了 8080 端口,這是 Spring Boot 應用的常用端口。
  6. Java 虛擬機設置
    • 啟用了服務器模式,優化長時間運行的性能。
    • 設置了初始和最大堆大小。
    • 啟用了 G1 垃圾收集器,適用于需要更可預測停頓時間和更好性能的應用程序。
    • 配置了在內存溢出時生成堆轉儲文件,有助于調試內存問題。
  7. 環境變量:允許通過 APP_ENV 命令行的應用 配置項。
  8. 目錄創建:創建了用于存儲內存轉儲文件和日志文件的目錄。
  9. 啟動命令:定義了容器啟動時執行的命令,包括 Java 虛擬機參數、日志文件設置和應用 jar 文件的執行。

2. 管理 Docker 容器:簡潔高效的腳本方法

管理 Docker 容器有時會顯得復雜。為此,我們使用 Bash 腳本來簡化這一過程。下面是這個腳本的核心要點:

  1. 安全性優先 - 使用 set -e 確保腳本在出現任何錯誤時立即停止,防止問題擴散。
  2. 靈活配置 - 通過設置變量 CONTAINER_NAMEIMAGE_NAME,腳本可以靈活適應不同的項目需求,會根據maven打包環境替換
  3. 容器重啟 - 如果容器正在運行,腳本會先停止并刪除它,然后重新構建和啟動,保證環境的干凈和更新。
  4. 一鍵執行 - 無論是構建新鏡像還是啟動新容器,一切操作都可通過腳本一鍵完成。

restart.sh

#!/bin/bash# 設置腳本在遇到錯誤時立即退出
set -e# 設置容器名稱和鏡像名稱
CONTAINER_NAME="${project.build.finalName}"
IMAGE_NAME="${project.build.finalName}:1.0.0"# 檢查容器是否存在并獲取其運行狀態
running=$(docker inspect --format="{{ .State.Running }}" "${CONTAINER_NAME}" 2>/dev/null || true)# 停止并刪除正在運行的容器
if [ "$running" == "true" ]; thenecho "Stopping running container..."docker stop "${CONTAINER_NAME}"echo "Removing stopped container..."docker rm -f "${CONTAINER_NAME}"
fi# 如果容器不存在或已停止,重新構建并啟動容器
if [ "$running" != "true" ]; then# docker load -i java8.tarecho "Building new image..."docker build -t "${IMAGE_NAME}" .echo "Starting new container..."docker run -d --name "${CONTAINER_NAME}" \--cap-add=SYS_PTRACE \-p 8080:8080 \-v "$(pwd)/dumps:/app/dumps" \-v "$(pwd)/logs:/app/logs" \"${IMAGE_NAME}"echo "Container has been restarted."
fi

docker load -i java8.tar 這一步對于下面Docker-Compose 可能是需要的。

3. 集成 Docker 管理腳本與 Maven:完善構建流程

要將前面提到的 Docker 管理腳本(restart.sh)以及 Dockerfile 與 Maven 打包工具集成,我們可以利用 Maven 的 maven-resources-plugin 插件。這個插件允許我們在 Maven 的構建過程中復制和處理資源文件。下面是如何配置這個插件,以及它在整個過程中的作用:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version><executions><execution><phase>process-resources</phase><goals><goal>resources</goal></goals><configuration><outputDirectory>${project.build.directory}</outputDirectory><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>Dockerfile</include><include>restart.sh</include></includes></resource></resources></configuration></execution></executions>
</plugin>

如果你看過
動態切換 Spring Boot 打包配置:使用 Maven Profiles 管理 JAR 和 WAR

可以跟 profile 結合起來,只有jar包的的時候才用Docker

<profiles><profile><id>jar</id><activation><activeByDefault>true</activeByDefault></activation><properties><packaging.type>jar</packaging.type></properties><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version><executions><execution><phase>process-resources</phase><goals><goal>resources</goal></goals><configuration><outputDirectory>${project.build.directory}</outputDirectory><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>Dockerfile</include><include>restart.sh</include></includes></resource></resources></configuration></execution></executions></plugin></plugins></build></profile>
</profiles>
  1. 執行階段:
    • 插件配置在 process-resources 階段執行,這是 Maven 生命周期中處理項目資源的標準階段。
    • goal 設置為 resources,表示插件的主要任務是處理資源。
  2. 資源配置:
    • outputDirectory 設置為 ${project.build.directory},這意味著資源將被復制到 Maven 的構建目錄中。
    • <resources>部分,我們定義了要包括的具體資源。
      • directory 指定資源所在的目錄,這里是 src/main/resources
      • filtering 設置為 true,允許對資源文件進行過濾處理,這對于包含需要替換的 Maven 屬性的文件很有用。
      • includes 標簽下,我們明確列出了要包含的文件:Dockerfilerestart.sh

通過這種方式,Maven 在構建過程中會自動將 Dockerfilerestart.sh 腳本復制到指定的輸出目錄。這樣做的好處是,你可以確保在最終的發版物中包含了這些對于部署和管理 Docker 容器至關重要的文件,實現了項目的一體化管理。

4. 從 Dockerfile 到 Docker-Compose:簡化和自動化應用部署

version: '2'services:${project.build.finalName}:  # 使用 Dockerfile 中定義的項目名作為服務名稱image: ${project.build.finalName}:1.0.0  # 使用 Dockerfile 中定義的鏡像名和標簽container_name: ${project.build.finalName}  # 容器名稱也使用同樣的命名ports:- "8080:8080"  # 暴露的端口volumes:- ./${project.build.finalName}.jar:/app/${project.build.finalName}.jar  # 掛載 JAR 文件- ./application.yml:/app/application.yml  # 掛載配置文件- ./application-${activatedProperties}.yml:/app/application-${activatedProperties}.yml  # 掛載特定環境的配置文件- ./dumps:/app/dumps  # 掛載內存轉儲目錄- ./logs:/app/logs  # 掛載日志目錄environment:- TIME_ZONE=Asia/Shanghai  # 設置時區- JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps/oom_dump.hprof- APP_ENV=-Dapp.log.serviceName=${project.build.finalName} --spring.profiles.active=${activatedProperties}restart: always  # 設置容器總是自動重啟logging:driver: json-fileoptions:max-size: "20m"max-file: "1"
動態配置與服務管理
  1. Maven 屬性集成:
    • 利用 Maven 屬性(如 ${project.build.finalName})實現 Docker 配置與構建過程的緊密集成,使配置動態化和自動化。
  2. 鏡像和容器名稱:
    • 根據 Maven 構建結果動態生成 imagecontainer_name,保證鏡像和容器名稱與項目版本一致。
  3. 端口映射:
    • ports 配置將容器內的端口(例如 8080)映射到宿主機,使外部訪問成為可能。
數據管理與環境優化
  1. 卷掛載 (volumes):
    • 掛載包括 JAR 文件、配置文件以及日志和轉儲目錄,確保容器可以訪問所需的所有文件和數據。
  2. 環境變量 (environment):
    • 設置容器的環境變量,如時區和 Java 運行參數,優化容器的運行環境。
穩定性與日志管理
  1. 自動重啟 (restart):
    • 配置容器在退出時自動重啟,提高應用的穩定性和可靠性。
  2. 日志配置 (logging):
    • 設置日志驅動和相關選項(例如最大文件大小和數量),幫助有效管理容器日志。

總的來說,這一套 Docker 化的流程不僅降低了部署復雜性,還提升了效率,為在不同環境中部署應用提供了極大便利。這對于追求快速、可靠且一致的軟件部署流程的現代開發團隊來說,是一種至關重要的實踐。

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

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

相關文章

堆的實現(C語言版)

文章目錄 概述堆的實現初始化銷毀插入刪除取堆頂元素求堆的長度判斷堆是否為空 完整代碼 概述 如果有一個關鍵碼的集合K {k0,k1,k2…kn-1}&#xff0c;把它的所有元素按完全二叉樹的順序存儲方式存儲在一個一維數組中&#xff0c;并滿足&#xff1a;Ki <K2*i1 且 Ki<K2…

Python Opencv實踐 - 全景圖片拼接stitcher

做一個全景圖片切片的程序Spliter 由于手里沒有切割好的全景圖片資源&#xff0c;因此首先寫了一個切片的程序spliter。 如果有現成的切割好的待拼接的切片文件&#xff0c;則不需要使用spliter。 對于全景圖片的拼接&#xff0c;需要注意一點&#xff0c;各個切片圖片之間要有…

NX二次開發UF_CSYS_map_point 函數介紹

文章作者&#xff1a;里海 來源網站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_map_point Defined in: uf_csys.h int UF_CSYS_map_point(int input_csys, double input_point [ 3 ] , int output_csys, double output_point [ 3 ] ) overview 概述 Ma…

Android11編譯第七彈:串口文件讀寫

問題&#xff1a;需要對SIM卡進行管理&#xff0c;支持APP切換SIM卡。此功能需要訪問串口文件&#xff0c;并且對串口文件進行讀寫。APP操作串口文件/dev/ttyUSB1時&#xff0c;串口文件打開失敗。 2023-11-23 10:59:44.092 14264-14264 MULTI_CARD_SerialHandle com.wellnkio…

三分鐘快速理解 ChatGPT 背后的大模型技術

在過去的十年中&#xff0c;人工智能領域取得了重大突破&#xff0c;其中自然語言處理&#xff08;NLP&#xff09;是其重要子領域之一。NLP使用的模型之一是大型語言模型&#xff08;LLMs&#xff09;。LLMs被設計用于處理大量文本數據&#xff0c;采用先進的神經網絡架構&…

nodejs 文件目錄監聽 chokidar watchpack

文件監聽實現&#xff0c;推薦使用chokidar&#xff1a; chokidar 默認是基于事件監聽文件 const chokidar require("chokidar"); const folderToWatch path.join(__dirname, "lib"); const watcher chokidar.watch(folderToWatch, { ignored: /(^|[…

在Vue中使用Echarts

文章目錄 Echarts1. 介紹2. 體驗NPM 安裝 Echarts定義 Echarts 容器引入 Echarts 3. 基礎配置 Echarts 1. 介紹 常見的數據可視化庫&#xff1a; D3.js 目前 Web 端評價最高的 Javascript 可視化工具庫(入手難)ECharts.js 百度出品的一個開源 Javascript 數據可視化庫Highch…

鼠標拖拽問題,不選中文本不觸發單擊事件

文章目錄 1. 為什么鼠標單擊的時候觸發了mousemove事件&#xff1f;明明鼠標沒有移動2. 鼠標拖拽元素怎么能不觸發單擊事件&#xff1f;怎么處理鼠標在元素內的相對定位&#xff0c;而不是每次定位到左上角&#xff1f;方式一&#xff1a;拖拽的元素沒有注冊click監聽就不會觸發…

10年測試老鳥,自動化測試經驗10條建議,一路狂飆...

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 1、哪一刻&#x…

Java面試題(每天10題)-------連載(37)

目錄 Mysql篇 1、Mysql如何優化DISTINCT&#xff1f; 2、如何輸入字符為十六進制數字&#xff1f; 3、如何顯示前50行&#xff1f; 4、可以使用多少列創建索引&#xff1f; 5、NOW()和CURRENT_DATE()有什么區別&#xff1f; 6、什么樣的對象可以使用CREATE語句創建&…

Postman如何使用(二):Postman Collection的創建/使用/導出分享等

一、什么是Postman Collection&#xff1f; Postman Collection是可讓您將各個請求分組在一起。 您可以將這些請求組織到文件夾中。中文經常將collection翻譯成收藏夾。如果再下文中看到這樣的翻譯不要覺得意外。Postman Collection會使你的工作效率更上一層樓。Postman Colle…

【洛谷 B2080】計算多項式的值 題解(順序結構+四則運算)

計算多項式的值 題目描述 假定多項式的形式為 x n x ( n ? 1 ) x^nx^{(n-1)} xnx(n?1) … x 2 x 1 x^2x1 x2x1&#xff0c;請計算給定單精度浮點數 x x x 和正整數 n n n 值的情況下這個多項式的值。多項式的值精確到小數點后兩位&#xff0c;保證最終結果在 doub…

NFS 速度變慢問題排查 性能優化

NFS 使用 RPC 來進行客戶端和服務器之間的通信。而在 RPC 的底層&#xff0c;NFS 使用 TCP 來進行數據的可靠傳輸&#xff0c;以便客戶端和服務器之間能夠有效地傳輸文件和進行遠程調用&#xff08;默認為TCP,也可調整為udp&#xff09; 1.首先服務器端啟動RPC服務portmap&…

教師工作就業前景

在這個知識爆炸的時代&#xff0c;當老師無疑是社會發展的重要基石。隨著科技的進步和社會的發展&#xff0c;教育行業的需求也在不斷增長。那么&#xff0c;教師工作的就業前景如何呢&#xff1f; 我們來看看教師工作的市場需求。隨著國家對教育的重視和投入的增加&#xff0c…

C/C++ 實現Socket交互式服務端

在 Windows 操作系統中&#xff0c;原生提供了強大的網絡編程支持&#xff0c;允許開發者使用 Socket API 進行網絡通信&#xff0c;通過 Socket API&#xff0c;開發者可以創建、連接、發送和接收數據&#xff0c;實現網絡通信。本文將深入探討如何通過調用原生網絡 API 實現同…

「Java開發中文指南」IntelliJ IDEA插件安裝(一)

IntelliJ IDEA是java編程語言開發的集成環境。IntelliJ在業界被公認為最好的Java開發工具&#xff0c;尤其在智能代碼助手、代碼自動提示、重構、JavaEE支持、各類版本工具(git、svn等)、JUnit、CVS整合、代碼分析、 創新的GUI設計等方面的功能是非常強大的。 插件擴展了Intel…

【分布式】分布式中的時鐘

一、物理時鐘 vs 邏輯時鐘 時鐘的存在主要是為了標識事件的發生順序。 分布式系統不使用物理時鐘記錄事件&#xff0c;分布式系統中每個節點記錄的時間并不一樣&#xff0c;即使設置了 NTP 時間同步節點間也存在毫秒級別的偏差 所以需要有另外的方法記錄事件順序關系&#x…

vue2中使用echarts

1,安裝echarts npm install --save echarts 2&#xff0c;具體頁面 <template><div class"app-container"><div class"aa" id"main" style"width: 500px; height: 400px;"></div></div> </te…

PDF 批量處理軟件BatchOutput PDF mac中文版介紹

BatchOutput PDF mac是一款適用于 Mac 的 PDF 批量處理軟件。它可以幫助用戶將多個 PDF 文件進行異步處理&#xff0c;提高工作效率。 BatchOutput PDF 可以自動化執行許多任務&#xff0c;包括 PDF 文件的打印、轉換、分割、壓縮、加密、重命名等&#xff0c;而且它還可以將自…

Elasticsearch知識

目錄 Elasticsearch邏輯設計和物理設計 邏輯設計物理設計Elasticsearch原理 倒排索引文檔的分析過程保存文檔搜索文檔寫數據的底層原理 數據刷新&#xff08;fresh&#xff09;事務日志的寫入ES在大數據量下的性能優化 文件系統緩存優化數據預熱文檔&#xff08;Document&…