多阶段分层构建容器化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.jar

RUN 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.mfbz.cn/a/756797.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4.x86游戏实战-人物状态标志位

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;3.x86游戏实战-寄存器 人物状态标志位&#xff1a; 什么叫人物状态标志位&…

PAE:从潮流报告中提炼有效产品属性

本文将介绍PAE&#xff0c;一种用于包含 PDF格式的文本和图像的产品属性提取算法。目前大部分的方法侧重于从标题或产品描述中提取属性&#xff0c;或利用现有产品图像中的视觉信息。与之前的工作相比&#xff0c;PAE从潮流趋势报告的PDF文件中提取属性&#xff0c;提取的属性包…

Django 自定义标签

1&#xff0c;简单标签 1.1 添加自定义标签函数 Test/app5/templatetags/mytags.py from django import template register template.Library() register.simple_tag() def show_title(value, n):if len(value) > n:return f{value[:n]}...else:return value 1.2 添加视…

day02-Spark集群及参数

一、Spark运行环境变量问题(了解) 1-pycharm远程开发运行时&#xff0c;执行的是服务器的代码 2-通过本地传递指令到远程服务器运行代码时&#xff0c;会加载对应环境变量数据&#xff0c;加载环境变量文件是用户目录下的.bashrc文件 在/etc/bashrc 1-1 在代码中添加 使用os模块…

Debug 调试代码

我们使用 debug 的目的, 认为就是查看代码的执行过程的。 步骤&#xff1a; 1. 打断点 断点的意义是, debug 运⾏的时候, 代码会在断点处停下来不执行如果是想要查看代码的执行过程, 建议将断点放在第⼀行在代码 和 行号之间 点击,出现的红色圆点 就是断点, 再次点击可以取消 …

ros1仿真导航机器人 基础传感器数据读取

仅为学习记录和一些自己的思考&#xff0c;不具有参考意义。 1 仿真环境 gazebo、rviz、ros1 2 机器人模型 <?xml version"1.0"?> <robot name"wpb_home_gazebo"><link name"base_footprint"><visual><origin …

嫦娥六号平安回家,Smartbi非常荣幸参与中国航天项目

“小时不识月&#xff0c;呼作白玉盘。”李白的这句诗&#xff0c;承载了古人对月亮的美好想象与纯真童趣。今天&#xff0c;当我们仰望夜空&#xff0c;那轮明月不仅是诗词中的意象&#xff0c;更是科学探索的目标和梦想的寄托。 2024年6月25日14时07分&#xff0c;嫦娥六号返…

安全与加密常识(0)安全与加密概述

文章目录 一、信息安全的基本概念二、加密技术概述三、常见的安全协议和实践四、加密的挑战与应对 在数字时代&#xff0c;信息安全和加密已成为保护个人和企业数据不受侵犯的关键技术。本文将探讨信息安全的基础、加密的基本原理&#xff0c;以及实用的保护措施&#xff0c;以…

Python中相关软件安装

1. python安装 1.下载地址 https://www.python.org/downloads/2.选择安装版本 1. Anaconda安装 安装地址 -- 清华大学镜像站点 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/查看anaconda是否安装成功 2.conda安装好后&#xff0c;将镜像源修改为清华大学的镜像…

知识库在AI大模型中的使用流程

大模型知识库的使用流程通常包括以下关键步骤&#xff0c;大模型知识库的使用流程需要跨学科的知识和技能&#xff0c;包括自然语言处理、数据库管理、软件工程等。同时&#xff0c;也需要关注用户体验、性能优化、安全保护等方面&#xff0c;以提供高质量的知识服务。北京木奇…

封装了一个iOS滚动厨窗效果

效果图 背景 我们要实现如图的厨窗效果&#xff0c;不能通过在tableView底部添加一个背景图片的方式&#xff0c;因为这需要修改整个tableView的背景色为透明&#xff0c;影响到的范围太大&#xff0c;只能将这个效果局限在这个cell 中&#xff0c;然后通过监听tableView的滚动…

昇思MindSpore学习笔记3--张量 Tensor

一、张量Tensor概念 矢量、标量和其他张量的计算函数&#xff0c;有内积、外积、线性映射以及笛卡儿积等 张量坐标在 n 维空间内&#xff0c;有 nr 个分量 每个分量都是坐标的函数,变换时每个坐标分量都按规则作线性变换 张量是一种特殊的数据结构&#xff0c;类似于数组和…

npm安装包报错解决

目录 一&#xff1a;问题回顾 二:问题分析 三&#xff1a;npm降级或者升级 四&#xff1a;npm和node js 关系 一&#xff1a;问题回顾 今天在本地部署一个vue开发的项目&#xff0c;需要在本地看下运行情况&#xff0c;按照常规的操作就是在网站根目录运行npm install 安装…

如何制作鼠标悬浮后伸缩的搜索框

引言 许多博客都在使用的伸缩搜索框制作教程 成品展示&#xff08;颜色自行搭配&#xff09; 初步布局 居中盒子&&初始化样式 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewpo…

Nuxt3 的生命周期和钩子函数(五)

title: Nuxt3 的生命周期和钩子函数&#xff08;五&#xff09; date: 2024/6/29 updated: 2024/6/29 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt3中的六个核心生命周期钩子及其用法&#xff0c;包括build:done、build:manifest、builder:generateApp、…

[oeasy]python021_赛博宝剑铭文大赏_宝剑上的铭文_特殊符号和宝物

继续运行 &#x1f94b; 回忆上次内容 上次修改了 程序 将 石中剑变成了 红色 爱之大剑 可以 让宝剑 具有 更多铭文符号 和 颜色 吗&#xff1f;&#x1f914; 铭文 亚瑟王 从石头中 取得宝剑 说明 不列颠科技从石器时代 进入了 青铜时代 第一把 Caliburn 断裂 第二把 湖中仙…

恢复的实现技术-日志和数据转储

一、引言 在系统正常运行的情况下&#xff0c;事务处理的恢复机制应采取某些技术措施为恢复做好相应的准备&#xff0c;保证在系统发生故障后&#xff0c;能将数据库从一个不一致的错误状态恢复到一个一致性状态 恢复技术主要包括 生成一个数据库日志&#xff0c;来记录系统中…

iOS开发中用到的自定义UI库

文章目录 前言cell 左右滑动菜单日历组件仿QQ 侧滑抽屉仿探探、陌陌的卡牌滑动库头部缩放视图自定义UITabbar刮刮乐广告横幅 前言 本文中的UI组件&#xff0c;是作者在移动应用开发中都用到过的。 确实&#xff0c;找到对的三方库可以快速帮助我们构建App, 极大程度上提高了生…

ESP32-C2模组数据透传模式配置详细教程

文章目录 1. 背景2. 关键步骤2.1 烧录AT指令固件2.2 配置透传模式2.3 如何退出透传模式重新配置3. 思考1. 背景 最近做的项目中,有蓝牙+WIFI的数据透传的需求,即系统A和系统B之间的通讯通过无线的方式,其实在实际项目中有很多这种场景比如无线调试手柄、无线数据终端、无线…

c进阶篇(一):数据的存储

1.数据类型介绍 char // 字符数据类型 short // 短整型 int // 整形 long // 长整型 long long // 更长的整形 float // 单精度浮点数 double // 双精度浮点数 1.1整形家族&#xff1a; char unsigned char signed char …