问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

简简单单将Java应用封装成Docker镜像

发布网友 发布时间:2024-09-29 03:32

我来回答

1个回答

热心网友 时间:2024-11-15 03:07

想必Docker这个词大家都不陌生,是一个非常优秀的虚拟化容器。

我的博客

怎么把Java应用打包成Docker镜像?对熟悉Docker的同学这应该是一个很简单的问题,把项目打包成JAR包然后在Dockerfile里用ADD命令把JAR文件放到镜像里,启动命令设置执行这个JAR文件即可。

可是对于不懂Java的,听起来貌似并不是那么简单。

在这之前,我们先了解了解什么是:Dockerfile。

Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

比如一个使用Maven构建的Spring应用就可以用下面这个Dockerfile构建镜像。

FROM openjdk:8-jre ADD target/*.jar /application.jar ENTRYPOINT ["java", "-jar","/application.jar"]

咦?这是啥语言,也没见过啊?这个其实是dockerfile的指令。

上面这个Dockerfile的指令很好理解,使用Maven构建的Java项目的目录结构统一是:

project │ pom.xml └───src // 源文件目录 │ │ │ └───main │ ││ └───java │└───target // class和jar文件的目录

用mvn clean package打包后会把JAR文件生成在target目录里,通过java -jar命令即可执行编译好的程序。

所以上面的Dockerfile里就进行了把JAR从target目录里添加到Docker镜像中以及将jar -jar /application.jar 设置成容器的启动命令这两步操作。

不过除了这种最原始的方法外我们还可以使用Maven的一些插件,或者Docker的多阶段打包功能来完成把Java应用打包成Docker镜像的动作。

Maven插件构建镜像

Spotify公司的dockerfile-maven-plugin和Google公司出品的jib-maven-plugin是两款比较有名的插件,下面简单介绍一下dockerfile-maven-plugin的配置和使用。

其实使用方法很简单,我们在POM文件里引入这个plugin,并结合上面那个Dockerfile就能让插件帮助我们完成应用镜像的打包。

<groupId>com.example</groupId> <artifactId>hello-spring</artifactId> <version>0.0.1-SNAPSHOT</version> <name>helloworld</name> <plugin><groupId>com.spotify</groupId><artifactId>dockerfile-maven-plugin</artifactId><version>1.4.10</version><executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <repository>${docker.registry.url}/${image.prefix}/${artifactId}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin>

插件里使用的docker.registry.url和image.prefix是我单独为Docker的镜像仓库设置的属性。

<properties><java.version>1.8</java.version> <image.prefix>kevinyan001</image.prefix> <docker.registry.url></private.registry.url> </properties>

这里可以随意设置成私有仓库的远程地址和镜像前缀,比如在阿里云的镜像服务上创建一个叫docker-demo的空间,上面的属性就需要这样配置:

<properties> <java.version>1.8</java.version> <image.prefix>docker-demo</image.prefix> <docker.registry.url>registry.cn-beijing.aliyuncs.com</docker.registry.url> </properties>

在POM文件里配置好插件后伴随着我们打包应用执行mvc clean package操作时dockerfile-maven-plugin就会自动根据我们的配置打包好一个叫做kevinyan001/hello-spring:0.0.1-SNAPSHOT的Docker镜像。

dockerfile-maven-plugin除了能帮助我们打包应用镜像外还可以让它帮助我们把镜像push到远端仓库,不过我觉得用处不大,感兴趣的同学可以去网上搜搜看这部分功能怎么配置。

Docker的多阶段构建打包镜像

上面介绍了使用Maven插件帮助我们打包Java应用的镜像,其实我们还可以把mvn clean package这一步也交给Docker来完成。当然把Java应用的源码放在Docker镜像里再编译打包在发布出去肯定是有问题的,我们知道在Dockerfile里每个指令ADD、RUN这些都是在单独的层上进行,指令越多会造成镜像越大,而且包含Java项目的源码也是一种风险。

不过好在后来Docker支持了多阶段构建,允许我们在一个Dockerfile里定义多个构建阶段,先拉起一个容器完成用于的构建,比如说我们可以在这个阶段里完成JAR的打包,然后第二个阶段重新使用一个jre镜像把上阶段打包好的JAR文件拷贝到新的镜像里。

使用下面的Dockerfile可以通过多阶段构建完成Java应用的Docker镜像打包。

# Dockerfile也可以不放在项目目录下,通过 -f 指定Dockerfile的位置,比如在项目根下执行以下命令docker build -t <some tag> -f <dirPath/Dockerfile> .FROM kevinyan001/aliyun-mvn:0.0.1 AS MAVEN_BUILDCOPY pom.xml /build/ COPY src /build/srcWORKDIR /build/ # mount anonymous host directory as .m2 storage for contianerVOLUME /root/.m2RUN mvn clean package -Dmaven.test.skip=true --quietFROM openjdk:8-jre COPY --from=MAVEN_BUILD /build/target/*.jar /app/application.jarENTRYPOINT ["java", "-jar", "/app/application.jar"]

上面我们用的这些Dockerfile也可以不用放在项目的根目录里,现在已经支持通过 -f 指定Dockerfile的位置,比如在项目根下执行以下命令完成镜像的打包。

docker build -t kevinyan001/hello-spring:0.0.1 -f <dirPath/Dockerfile> .

上面第一个镜像是我自己做的,因为Maven官方的镜像的远程仓库慢的一批,只能自己包装一下走阿里云的镜像源了。试了试速度也不快,主要是随随便便一个Spring项目依赖就太多了。大家如果这块有什么加快Docker 构建速度的方法也可以留言一起讨论讨论。

不可否认用多阶段构建打出来的Go镜像基本上是10M左右,但是Spring的应用随随便便就是上百兆,这个对容器的构建速度、网络传输成本是有影响的,那么Spring应用的镜像怎么瘦身呢,这个就留到以后的文章进行探讨了。

原文:https://juejin.cn/post/7101567538546343949
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果电脑电池充不进电苹果电脑充不进去电是怎么回事 苹果电脑不充电没反应苹果电脑充电指示灯不亮充不了电怎么办 狗狗更加忠诚护家、善解人意,养一只宠物陪伴自己,泰迪能长多大... 描写泰迪狗的外形和特点的句子 国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? 刚补完牙后牙疼正常吗 苹果5s怎么查最近一次激活时间?IMEI是358776055340841 苹果5S怎么查看生产日期F93P42LCFR9L 课堂教学研课活动参会人是谁? 微信豆怎么退 你怎样评价这位教师的课堂教学? 你认为课堂教学与课程标准之间有必要保持一致吗? 为什么我的微信豆充了不能退款? 冰箱密封条为什么发烫? 怎样选购主板芯片组? 开心一刻幽默小笑话(笑到抽筋的笑话) Intel芯片组分类命名 25个笑到抽筋的笑话 乙肝病毒表面抗体阳性什么意思 检测出乙肝表面抗体呈阳性是什么意思啊,是 乙肝表面抗体为阳性是什么意思 闷骚型的女人有哪些表现? ownory是什么牌子 宋庆龄的丈夫是谁宋庆龄的丈夫是哪位呢 为什么说DOTA657b中能隐行的英雄增强了呢? ORBSLAM3--学习总结(5)将ORB-SLAM3及相关依赖打包成Docker镜像 Docker打包Node.js项目为镜像 高中2022开学祝福语 买二手笔记本电脑去哪个平台? 3003yy里面我买的脚本怎么用不了 求十条超级搞笑极品笑话,每条5 岛国宅男神级YY福利片——《也许曾经能做到委员会》 1.5匹加氟多少钱 试问下,现在YY上面盛传的脚本,能不能用 为什么我用大脚的时候YY按键没用了 空调加氟价格一般是多少啊? 地理环境闭塞是什么意思 行政职业能力倾向测验大纲解读 新编公务员录用考试教材:行政职业能力测验内容简介 usb驱动程序被禁用,该如何打开? 2024年QQ是不是要关闭了? 听说qq要关闭,是真的吗?? qq软件要关闭了吗 qq要关闭了吗官网 请问qq真的要关闭了吗?