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}"]
包含如下基本功能:
- 设置时区为Asia/Shanghai
- 自动获取 maven 应用包名,不需要额外修改即可使用。
- 自动识别 profile 使用的配置文件 不管是 application-dev.yml 、*-test.yml *.prod.yml 都可以识别出来。
- 默认暴漏8080端口
以下是它的主要特点和功能:
- 基础镜像:使用了
Java 8我自定义的镜像,你们使用dockerhub 上的就行 的基础镜像,这适用于许多传统的 Java 应用程序。 - 时区设置:设置时区为
Asia/Shanghai。这是一个重要的设置,特别是对于需要关注本地时间的应用程序。如果需要,可以轻松更改为其他时区。 - 工作目录:在容器内设置了
/app作为工作目录。 - 文件复制:将构建的 Spring Boot 应用 jar 文件以及相关的配置文件(
application.yml和application-${activatedProperties}.yml)复制到镜像中,自动识别 profile 使用的配置文件 。 - 端口暴露:默认暴露了 8080 端口,这是 Spring Boot 应用的常用端口。
- Java 虚拟机设置:
- 启用了服务器模式,优化长时间运行的性能。
- 设置了初始和最大堆大小。
- 启用了 G1 垃圾收集器,适用于需要更可预测停顿时间和更好性能的应用程序。
- 配置了在内存溢出时生成堆转储文件,有助于调试内存问题。
- 环境变量:允许通过
APP_ENV命令行的应用 配置项。 - 目录创建:创建了用于存储内存转储文件和日志文件的目录。
- 启动命令:定义了容器启动时执行的命令,包括 Java 虚拟机参数、日志文件设置和应用 jar 文件的执行。
2. 管理 Docker 容器:简洁高效的脚本方法
管理 Docker 容器有时会显得复杂。为此,我们使用 Bash 脚本来简化这一过程。下面是这个脚本的核心要点:
- 安全性优先 - 使用
set -e确保脚本在出现任何错误时立即停止,防止问题扩散。 - 灵活配置 - 通过设置变量
CONTAINER_NAME和IMAGE_NAME,脚本可以灵活适应不同的项目需求,会根据maven打包环境替换 - 容器重启 - 如果容器正在运行,脚本会先停止并删除它,然后重新构建和启动,保证环境的干净和更新。
- 一键执行 - 无论是构建新镜像还是启动新容器,一切操作都可通过脚本一键完成。
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>
- 执行阶段:
- 插件配置在
process-resources阶段执行,这是 Maven 生命周期中处理项目资源的标准阶段。 goal设置为resources,表示插件的主要任务是处理资源。
- 插件配置在
- 资源配置:
outputDirectory设置为${project.build.directory},这意味着资源将被复制到 Maven 的构建目录中。- 在
<resources>部分,我们定义了要包括的具体资源。directory指定资源所在的目录,这里是src/main/resources。filtering设置为true,允许对资源文件进行过滤处理,这对于包含需要替换的 Maven 属性的文件很有用。includes标签下,我们明确列出了要包含的文件:Dockerfile和restart.sh。
通过这种方式,Maven 在构建过程中会自动将 Dockerfile 和 restart.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"
动态配置与服务管理
- Maven 属性集成:
- 利用 Maven 属性(如
${project.build.finalName})实现 Docker 配置与构建过程的紧密集成,使配置动态化和自动化。
- 利用 Maven 属性(如
- 镜像和容器名称:
- 根据 Maven 构建结果动态生成
image和container_name,保证镜像和容器名称与项目版本一致。
- 根据 Maven 构建结果动态生成
- 端口映射:
ports配置将容器内的端口(例如 8080)映射到宿主机,使外部访问成为可能。
数据管理与环境优化
- 卷挂载 (
volumes):- 挂载包括 JAR 文件、配置文件以及日志和转储目录,确保容器可以访问所需的所有文件和数据。
- 环境变量 (
environment):- 设置容器的环境变量,如时区和 Java 运行参数,优化容器的运行环境。
稳定性与日志管理
- 自动重启 (
restart):- 配置容器在退出时自动重启,提高应用的稳定性和可靠性。
- 日志配置 (
logging):- 设置日志驱动和相关选项(例如最大文件大小和数量),帮助有效管理容器日志。
总的来说,这一套 Docker 化的流程不仅降低了部署复杂性,还提升了效率,为在不同环境中部署应用提供了极大便利。这对于追求快速、可靠且一致的软件部署流程的现代开发团队来说,是一种至关重要的实践。
相关文章:
Spring Boot 应用的 Docker 化:从 Maven 构建到 Docker 部署的完整指南
1. 使用Dockerfile部署 # 使用Java 8基础镜像 FROM java:8 LABEL authors"mabh"# 设置时区为Asia/Shanghai,可以根据需要更改 ENV TIME_ZONEAsia/Shanghai# 更新时区 RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_…...
linux之chmod命令
在linux系统中经常遇到需要对文件修改读写执行的权限,下面对chomod命令进行梳理总结。 1、文件权限 在linux系统中,每个文件都有归属的所有者和所有组,并且规定了文件的所有者、以及其他人对文件所拥有的可读(r)、可写…...
论文阅读 Forecasting at Scale (一)
最近在看时间序列的文章,回顾下经典 论文地址 项目地址 Forecasting at Scale 摘要1、介绍2、时间业务序列的特点3、Prophet预测模型3.1、趋势模型3.1.1、非线性饱和增长3.1.2、具有变化点的线性趋势3.1.3、自动转换点选择3.1.4、趋势预测的不确定性 摘要 预测是一…...
Unity PlayerPrefs相关应用
PlayerPrefs是Unity游戏引擎中的一个类,用于在游戏中存储和访问玩家的偏好设置和数据。它可以用来保存玩家的游戏进度、设置选项、最高分数等信息。PlayerPrefs将数据存储在本地文件中,因此可以在游戏重新启动时保持数据的持久性。 //PlayerPrefs的数据…...
LeetCode题解:13. 罗马数字转整数,哈希表,JavaScript,详细注释
原题链接:13. 罗马数字转整数 解题思路: 本题涉及到的罗马数字都是唯一的,因此可以创建一个哈希表,存储罗马数字和整数的对应关系。遍历s,分别截取从i开始的2位和1位字符串,查看其在哈希表中的罗马数字对…...
GPT2-chitchat项目运行
git clone https://github.com/yangjianxin1/GPT2-chitchat.git把项目拉下来 下载模型文件: 从[模型分享]中下载模型文件,例如 model_epoch40_50w。 将模型文件放到正确的位置: 将下载的模型文件夹 model_epoch40_50w 放到项目的 model 目录…...
selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(3)
接前一篇文章:selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(2) 4. 重点文件内容解析 (1)control/postist文件 上一回讲解了postinst文件的前一部分内容,本回继续往下解析。为了便于理解,再次贴出postinst完整代码: #!/bin/sh set -e# summary of ho…...
Spring boot @Bean
Bean 是 Spring 框架中的一个注解,它的作用是将一个方法标记为 Spring 容器中的一个 Bean。具体来说,当你在一个类中使用 Bean 注解修饰一个方法时,这个方法将会在 Spring 容器中执行,并且返回的对象也会被 Spring 容器管理。 Be…...
ptpd2提示failed to join the multicast group (strerror: No buffer space available)
下载交叉编译ptpd-ptpd-2.3.1源码,在IMX6板子上面运行ptpd2提示错误如下: rootimx6qsabresd_genvict:~# ./ptpd2 -C -m -i eth0 2023-11-24 14:30:21.484399 ptpd2[6512].startup (info) (___) Configuration OK 2023-11-24 14:30:21.487152 ptpd2…...
工业级5G路由器:稳定性更高,网络速度更快!
随着5G技术的发展,5G路由器也越来越受到人们的关注。特别是工业级5G路由器,它的应用范围更广,稳定性更高,网络速度更快,已成为许多企业和工业领域的必备选择。 一、工业级5G路由器的特点 工业级5G路由器具有很多独特的…...
移动应用程序管理的内容、原因和方式
移动应用程序管理(MAM)是一个术语,指的是管理应用程序的整个生命周期,包括从设备安装、更新和卸载应用程序,除了在整个生命周期内管理设备外,MAM 还包括保护应用访问的数据,以及在设备上发现恶意…...
Revive开发商加入VR开源标准OpenXR
作为一款能让HTC Vive用户玩到Oculus平台游戏的软件,它的开发商CrossVR今日宣布即将加盟为VR和AR应用程序开源组织,即OpenXR。 由Khronos Group引领的OpenXR旨在创建一个标准化且免版税的应用程序编程接口(API),该API…...
Lambda 重构面向对象的设计模式
Lambda 重构面向对象的设计模式 策略模式 策略模式包含三部分内容 一个代表某个算法的接口(它是策略模式的接口)。 一个或多个该接口的具体实现,它们代表了算法的多种实现(比如,实体类ConcreteStrategyA或者Concrete…...
element ui 上传组件实现手动上传
首先需要给上传组件增加http-request属性,这个方法中可以获取到文件,并按照自己的方式进行上传。 <el-uploadreffileUploadaction#:http-requesthttpRequest:on-preview"handlePreview":on-remove"handleRemove":limit"1&q…...
怎样提升伦敦银买卖技巧?
如果投资者想提升伦敦银的买卖技巧,可以学习一些有用的技术分析方法。所谓技术分析,就是通过对行情过往价格和相关交易数据进行收集,用图表的方式解读白银市场,进而预测行情未来主线走势、判断价格细节变化、寻找重要支撑点阻力点…...
MySQL的体系结构与SQL的执行流程
文章目录 前言体系结构SQL语句的执行流程1、连接MySQL2、查询缓存3、解析SQL语句4、优化SQL语句5、执行SQL语句 总结 前言 如果你在使用MySQL时只会写sql语句的,那么你应该看一下《MySQL优化的底层逻辑》。如果你只了解到sql是如何优化的,那么你应该通过…...
数学建模之拟合及其代码
发现新天地,欢迎访问Cr不是铬的个人网站 引言 与插值问题不同,在拟合问题中不需要曲线一定经过给定的点。拟合问题的目标是寻求一个函数(曲线),使得该曲线在某种准则下与所有的数据点最为接近,即曲线拟合…...
GeoTrust SSL数字安全证书介绍
一、GeoTrust OV证书的介绍 GeoTrust OV证书是由GeoTrust公司提供的SSL证书,它是一种支持OpenSSL的数字证书,具有更高的安全性和可信度。GeoTrust是全球领先的网络安全解决方案提供商,为各类用户提供SSL证书和信任管理服务。GeoTrust OV证书…...
【C++上层应用】5. 文件和流
文章目录 【 1. 打开文件 】1.1 open 函数1.2 open 多种模式的结合使用 【 2. 关闭文件 】【 3. 写入 & 读取文件 】【 4. 文件位置指针 】 和 iostream 库中的 cin 标准输入流和 cout 标准输出流类似,C中另一个库 fstream 也存在文件的读取流和标准写入流。fst…...
JAVA爬虫1 - HttpClient的使用
一、简介 HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的 项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit…...
3个真实场景,教你用Excalidraw手绘白板提升团队协作效率
3个真实场景,教你用Excalidraw手绘白板提升团队协作效率 【免费下载链接】excalidraw Virtual whiteboard for sketching hand-drawn like diagrams 项目地址: https://gitcode.com/GitHub_Trending/ex/excalidraw 想象一下:你正在远程会议中解释…...
Windows VEH异常处理实战:用C++写一个无痕Hook框架(附完整源码)
Windows VEH异常处理框架深度解析:从原理到工程实践 在Windows系统开发领域,异常处理机制一直是构建健壮软件系统的核心技术之一。VEH(Vectored Exception Handling)作为Windows异常处理体系中的重要组成部分,不仅为开…...
TensorRT模型部署提速:除了trtexec,Windows下还有哪些转换ONNX到engine的实用方法?
TensorRT模型部署提速:Windows下ONNX到engine的5种高效转换方案 在工业级AI部署中,模型推理速度直接影响用户体验和系统成本。TensorRT作为NVIDIA推出的高性能推理优化器,能将ONNX模型转换为高度优化的engine文件,实现数倍的推理加…...
深度解析:碧蓝航线Alas脚本的自动化架构与实战应用
深度解析:碧蓝航线Alas脚本的自动化架构与实战应用 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 在手游生命周…...
数字孪生落地指南与技术选型:从选型到交付全流程避坑实战 | 数字孪生实战训练营
⚠️ 说明:本文内容偏实践经验总结,更适合有数字孪生项目背景或正在推进相关工作的读者阅读。 在数字化转型的深水区,数字孪生已不再仅仅是炫酷的视觉概念,而是深入业务一线、赋能决策的核心工具。然而,从概念雏形到最…...
VSCode 2026启动卡顿、编辑迟滞、崩溃频发?这7个隐藏内存泄漏点99%开发者至今未修复!
更多请点击: https://intelliparadigm.com 第一章:VSCode 2026内存问题的根源诊断与量化评估 VSCode 2026 版本引入了基于 WebAssembly 的扩展沙箱和实时语义索引服务,但部分用户报告工作区打开后内存占用持续攀升至 4GB,且未随关…...
[Linux] Ubuntu 26.04 换阿里云镜像源(最新方法)
适用版本:Ubuntu 26.04 LTS(代号 resolute) 参考:阿里云开发者镜像站 Ubuntu 默认情况下,Ubuntu 从 archive.ubuntu.com 拉取软件包,国内访问速度缓慢,换成阿里云镜像源之后一般能提升 10x 以上…...
Unity UI粒子特效完整解决方案:高效实现专业级视觉效果
Unity UI粒子特效完整解决方案:高效实现专业级视觉效果 【免费下载链接】ParticleEffectForUGUI Render particle effect in UnityUI(uGUI). Maskable, sortable, and no extra Camera/RenderTexture/Canvas. 项目地址: https://gitcode.com/gh_mirrors/pa/Partic…...
ChatLog:终极QQ群聊天记录分析工具,三分钟解锁数据洞察力
ChatLog:终极QQ群聊天记录分析工具,三分钟解锁数据洞察力 【免费下载链接】chatLog QQ群聊天记录分析 项目地址: https://gitcode.com/gh_mirrors/ch/chatLog 你是否好奇过,在那些热闹的QQ群里,谁才是真正的"话痨之王…...
Cgo 回调中处理 const char- 参数的正确方法
本文详解如何在 Cgo 中为带 const char* 参数的 C 回调函数编写兼容的 Go 导出函数,解决因 const 修饰符导致的类型冲突编译错误,并提供安全、可移植的实践方案。 本文详解如何在 cgo 中为带 const char* 参数的 c 回调函数编写兼容的 go 导出函数&…...
