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.mzph.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; 该输出就是散列值。这种转换是一种压缩映射&…