多阶段分层构建容器化Spring Boot应用程序

上一节中,容器化spring boot应用程序-CSDN博客我们介绍了基于简单的Dockerfile对spring boot进行容器化的过程,本讲将介绍如何基于Dockerfile进行多阶段的分层构建过程,希望对大家有所帮助。

Spring Boot从版本2.3.0开始支持分层构建容器化的镜像,在使用时需要注意,本文使用的spring boot的版本是:3.3.1

创建spring boot应用程序

pom.xml 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.zgy</groupId><artifactId>container_docker</artifactId><version>0.0.1-SNAPSHOT</version><name>container_docker</name><description>container_docker</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.14.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.3.1</version><configuration><layers><enabled>true</enabled></layers><loaderImplementation>CLASSIC</loaderImplementation></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

需要注意的是使用的maven插件:spring-boot-maven-plugin ,为了使用容器化分层的能力,需要进行如下配置:

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.3.1</version><configuration><layers><enabled>true</enabled></layers><loaderImplementation>CLASSIC</loaderImplementation></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions>
</plugin>

如上图,需要关注configuration部分的配置以及executions中的设置,否则会导致后续分层配置的失败,本文是经过测试可使用的,大家可以直接复制即可。

创建应用的端点

@RestController
@RequestMapping(value = "/layer")
public class LayerController {@GetMapping(value = "test")public void test() {System.out.println("layers/test/....");}@GetMapping(value = "tttest")public void tttest() {System.out.println("ttt test test!!");}
}

如上图,创建了一个controller类,用于启动容器后的测试。

打包

mvn clean package

执行该命令后,会在target目录下创建*.jar的包,这个需要后续上传到linux上用于进行镜像的构建

Dockerfile配置文件

FROM openjdk:17-jdk-alpine as builder
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jarRUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:17-jdk-alpine
RUN mkdir app
WORKDIR app
COPY --from=builder dependencies/ ./
COPY --from=builder snapshot-dependencies/ ./
COPY --from=builder spring-boot-loader/ ./
COPY --from=builder application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
FROM openjdk:17-jdk-alpine as builder

该命令拉取open jdk 17的镜像,并将其作为第一个阶段

ARG JAR_FILE=target/*.jar

定义参数JAR_FILE,其值为之前打包的jar包程序

COPY ${JAR_FILE} application.jar

将打包后的jar包复制到容器内部,并重命名为application.jar

RUN java -Djarmode=layertools -jar application.jar extract

该命令是从application.jar中提取分层后的部分,这也是在maven中添加maven插件并添加配置的原因,否则无法提取jar包中的层级

FROM openjdk:17-jdk-alpine

开始第二个阶段,并使用jdk 17的镜像

RUN mkdir app

在容器内部创建目录app

WORKDIR app

将目录app作为上下文的工作环境

COPY --from=builder dependencies/ ./
COPY --from=builder snapshot-dependencies/ ./
COPY --from=builder spring-boot-loader/ ./
COPY --from=builder application/ ./

使用第一个阶段的内容,并将分层后的各个部分逐一的复制到容器内部

ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

容器启动后,启动应用程序,需要注意的是,我们不是使用的jar -jar application.jar,而是使用的org.springframework.boot.loader.launch.JarLauncher,这个需要设置正确,否则会导致找不到启动类的报错。

构建镜像

上传资源

将target目录以及Dockerfile上传到linux中,用于构建镜像,linux上传后的目录如下所示

构建镜像

docker  build -t layer:v1 .

镜像构建后,可以看到如下镜像  创建容器 

docker conainer run –p 3000:8080 –name layer layer:v1

可以通过调用自定义的端点,可以进行验证

后续代码发生变更后,通过以上步骤,重新打包、构建新的镜像、删除已有的容器并启动新的容器,便可完成进行新代码的部署工作 。后续执行镜像操作的过程中,会比较快,因为镜像会进行缓存,如下图所示

这也是docker镜像缓存以及spring boot支持分层所带来的优化效果 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/37700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql中varchar类型数字排序不对踩坑记录

场景 在进行表设计时将版本号字段设计了为varchar类型&#xff0c;尽量从表设计阶段将数字类型列设计为int型。 再进行排序时如果版本号累计到了10及以上&#xff0c;那么再进行排序时则会出现问题。 比如下面执行排序时发现10被排在了第一位。 这是因为 varchar类型对数字…

51单片机第8步_absacc.h库函数

本章重点学习库函数absacc.h的使用,介绍绝对宏和绝对地址的用法。故事有点老掉牙&#xff0c;但学校的教授们还在继续。 #include <REG52.h> //包含头文件REG52.h,使能51内部寄存器; #include <absacc.h> #include <stdio.h> //包含头文件stdio.h //_get…

已备案网站变更并且不影响现有业务的方案

已备案网站变更并且不影响现有业务的方案 近日有个工作上的需求&#xff0c;已备案网站变更并且不影响现有业务&#xff0c;记录一下。 需求 域名&#xff1a;XXXXXX.com备案变更前主体&#xff1a; 海南XXXXXX科技有限公司 备案变更后主体&#xff1a; 深圳XXXXXX科技有限…

【05】从0到1构建AI生成思维导图应用 -- 前端交互实现

【05】从0到1构建AI生成思维导图应用 – 前端交互实现 大家好&#xff01;最近自己做了一个完全免费的AI生成思维导图的网站&#xff0c;支持下载&#xff0c;编辑和对接微信公众号&#xff0c;可以在这里体验&#xff1a;https://lt2mind.zeabur.app/ 上一章&#xff1a;http…

【图解大数据技术】Hive、HBase

【图解大数据技术】Hive、HBase Hive数据仓库Hive的执行流程Hive架构数据导入Hive HBaseHBase简介HBase架构HBase的列式存储HBase建表流程HBase数据写入流程HBase数据读取流程 Hive Hive是基于Hadoop的一个数据仓库工具&#xff0c;Hive的数据存储在HDFS上&#xff0c;底层基于…

Linux 常用命令 - dd 【复制及转换文件内容】

简介 dd 命令源自于磁盘复制&#xff08;disk dump&#xff09;的缩写&#xff0c;是 Linux 和 Unix 系统中用于转换和复制文件的一个强大工具。它可以在复制过程中进行格式转换&#xff0c;支持不同的块大小&#xff0c;能够直接对硬盘设备进行操作&#xff0c;非常适合进行备…

android里面json操作

1.读取assets下面xzhd/aikit/pck.json String json = null; try { InputStream is = activity.getAssets().open(aikitPathInData+"xzhd/aikit/pck.json"); int size = is.available(); byte[] buffer = new byte…

容器进程

一、容器进程和宿主机进程的关系 容器在进程空间上和宿主机是隔离的&#xff0c;每创建一个容器&#xff0c;该容器都有一个独属的进程空间简称PID NameSpace。但是容器本质也是一个进程&#xff0c;自然是由其父进程创建的&#xff0c;这个可以使用ps aux命令验证。 | 容器视…

Windows 下写C++代码的必备

在 Windows 下写代码&#xff0c;还需要用到 Windows.h 头文件的话&#xff0c;需要记住以下两点&#xff1a; 一定要 predefine 一个宏&#xff0c;NOMINMAX&#xff0c;禁用掉 windows 定义的 min 和 max 宏 #include <winsock.h> #define WIN32_LEAN_AND_MEAN #defin…

【高考志愿】材料科学与工程

目录 一、专业概述 二、就业前景与方向 三、院校选择和报考建议 3.1 院校选择 3.2 报考建议 四、材料科学与工程专业排名 高考志愿选择材料科学与工程专业时&#xff0c;确实是一个需要深思熟虑的决策过程。以下是更详细和扩展的考虑因素&#xff1a; 一、专业概述 学习…

Tesseract Python 图片文字识别入门

1、安装tesseract Index of /tesseract https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-w64-setup-v5.3.0.20221214.exe 2、安装中文语言包 https://digi.bib.uni-mannheim.de/tesseract/tessdata_fast/ 拷贝到C:\Program Files\Tesseract-OCR\tessdata 3、注…

Java面试题:描述你如何向非技术人员解释技术概念

向非技术人员解释技术概念时&#xff0c;需要使用简单明了的语言&#xff0c;并结合类比和实际例子&#xff0c;使复杂的技术内容变得易于理解。以下是一些具体的策略&#xff1a; 使用类比&#xff1a; 熟悉的场景类比&#xff1a;将技术概念与日常生活中的熟悉事物进行类比。…

每天写java到期末考试--实验四---接口与抽象类--6.29

第一部分&#xff1a;接口与类的实现 Shape接口 java复制代码public interface Shape { double getArea(); double getPerimeter(); } Circle类 public class Circle implements Shape { private double r; public Circle(double r) { this.r r; } Override publ…

ISO26262标准

什么是ISO26262&#xff1f; ISO 26262(国际功能安全标准)是一个涵盖整个汽车产品开发过程的汽车功能安全标准。ISO 26262继承或改编自工业自动化行业的安全要求标准IEC61508&#xff0c;但专门为汽车行业量身定制。最新版本是ISO26262-1:2018。 它包括诸如需求分析、安全分析…

STM32CubeMx的学习记录系列(2)- STM32G474RET6

最近有个小比赛&#xff0c;需要用到G4&#xff0c;不过找了一圈没有找到标准库的代码&#xff0c;只能使用hal&#xff0c;用CubeMX来生成配置代码。 共同特点 ARDUINO Uno V3 扩展连接器 ST morpho 扩展引脚接头&#xff0c;可完全访问所有 STM32 I/O 采用LQFP64或LQFP48封…

51单片机第9步_结构和联合

本章重点学习结构和联合。 //结构和联合应用举例 #include <REG51.h> //包含头文件REG51.h,使能51内部寄存器; #include <stdio.h> //包含头文件stdio.h //_getkey();从串口读入一个字符; //putchar();向串口发送一个字节; //printf();向串口发送一串字节; /…

Llamaindex实战-在本地使用多种LLM

Llamaindex实战-在本地使用多种LLM 有关我们支持的大语言模型列表及其功能比较&#xff0c;请查看我们的大语言模型模块指南。 使用LLM的基本范式 构建基于 LLM 的应用程序时的第一步是决定使用哪个 LLM&#xff1b;也可以使用多个。 LLM 可用于管道的多个不同阶段&#xff…

6.29学习笔记

马克思 “流”&#xff1a;两个选它纺织厂生产的棉花属于&#xff1a;不变资本、流动资本&#xff1b;机器属于&#xff1a;不变资本、固定资本剩余价值生产的基本方法&#xff1a;绝对剩余价值、相对剩余价值货币的基本职能&#xff1a;价值尺度&#xff0c;流通手段“价格围…

p2p、分布式,区块链笔记: libp2p基础

通信密钥 noise::{Keypair, X25519Spec} X25519/Ed25519类似RSA 算法。Noise 用于设计和实现安全通信协议。它允许通信双方在没有预先共享密钥的情况下进行安全的密钥交换&#xff0c;并通过加密和身份验证保护通信内容。libp2p 提供了对 Noise 协议的原生支持&#xff0c;它允…

20、PHP字符串的排列(含源码)

题目&#xff1a; PHP字符串的排列&#xff1f; 描述&#xff1a; 输入一个字符串,按字典序打印出该字符串中字符的所有排列。 例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述&#xff1a; 输入一个字符串,长度不超过9(可…