该章主要围绕
dockerfile
+docker
在实际项目场景(Java
、Vue
、Go
)下的简单使用。
系列目录
LaoCat带你认识容器与镜像(一)
LaoCat带你认识容器与镜像(二【一章】)
LaoCat带你认识容器与镜像(二【二章】)
LaoCat带你认识容器与镜像(二【三章】)
LaoCat带你认识容器与镜像(三【上】)
LaoCat带你认识容器与镜像(三【下】)
LaoCat带你认识容器与镜像(四【上】)
LaoCat带你认识容器与镜像(四【下】)
LaoCat带你认识容器与镜像(番外一【Harbor】)
LaoCat带你认识容器与镜像(实践篇一上)
LaoCat带你认识容器与镜像(实践篇一下)
LaoCat带你认识容器与镜像(实践篇二上)
LaoCat带你认识容器与镜像(实践篇二下)
本章内容
本文实操全部基于Ubuntu 20.04
宿主机 => linux服务器本身
Docker => 20.10.22
JDK => 1.8
这一章围绕Dockerfile
与Docker
的结合使用并在实际场景下的应用,这里的实际场景指Java项目
、Vue项目
、Go项目
;这里我将演示项目全部上传到自己的GitHub
上,感兴趣的小伙伴可以通过文末的链接访问进行学习。
Dockerfile与Docker结合使用之Java项目
作为一名Java
开发,Java
语言的项目是再熟悉不过了,接下来我们通过Dockerfile
来构建其Docker
镜像,模拟实际日常开发如何结合Docker
使用,我们这里主要以Dockerfile
为主,项目相关不进行拓展,前置工作需要将Mysql
容器启动,文中用到的Mysql
为LaoCat带你认识容器与镜像(实践篇二上)
章节中启动并创建的容器。
-
首先我们创建一个
Spring Boot
项目,项目结构如下,该项目已上传Github
。
-
新建完项目后,我们再新建一个简单的接口,获取全部用户列表,然后检查项目是否可以正常启动,是否可以正常打包以及打包后的
Jar
是否可以正常启动。@GetMapping("/ping") public List<User> user() { return userService.user(); }
-
检查无误后,我们开始编写
Dockerfile
,有关Dockerfile
的相关内容,请阅读LaoCat带你认识容器与镜像(四【上】)
章节。FROM maven:3.8.1 AS package ADD ./pom.xml pom.xml ADD ./src src/ RUN mvn clean package FROM openjdk:8u102 AS JDK ENV TZ=Asia/Shanghai ENV JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY --from=package /target/springboot-docker-*.jar sbd.jar EXPOSE 8889 CMD java $JAVA_OPTS -jar sbd.jar
整个
Dockerfile
文件分为package
阶段与JDK
阶段。
-
package
阶段每一项命令到底做了什么?
-
JDK
阶段每一项命令到底做了什么?
不难发现,
Dockerfile
文件中的操作,实际上是将人为的每一步操作变为命令,而解放生产力。 -
接着我们将该项目上传到服务器上(③ 此处可以在
Dockerfile
处增加一阶段即为从Github
拉取代码到镜像中),进入到项目目录下(④Dockerfile
所在的目录,一般放在根目录),执行命令docker build -t spd:1.0 /home/ubuntu/springboot-docker/
(有关docker build
命令的相关说明请阅读LaoCat带你认识容器与镜像(四【下】)
章节),可以看到每一层构建的信息,Maven
阶段会比较浪费时间,前面已经说明过原因。 -
创建并启动该容器,执行命令
docker run -d -p 8889:8889 --link=mysql8 --name spd spd:1.0
。 -
执行命令
docker logs -f spd
,可以通过日志看到项目已经成功启动。
-
接着我们通过IP加端口访问该容器。
※ 4环节图中①拓展:在编译打包项目时,Maven
会对项目依赖进行下载,默认网速下,该步骤下载时间会随着项目依赖体量的增加而增加,有时还会因为项目依赖太大或项目依赖源在国外等情况,出现超时与失败,解决办法可以选择将Maven
替换为Gradle
或将编译打包阶段交给Jenkins
或云厂商的流水线去执行;也可以选择将对应依赖下载到Maven
私仓,将配置好的Maven
打包为镜像,Dockerfile
使用该Maven
镜像为基础镜像来解决。
※ 5环节图中②拓展:为什么要用*
来替换实际的版本呢?这是因为在实际生产环境中,Java
项目版本号会随着业务的迭代更新而更新,每次发布都需要进入该文件去改一下版本号,并不是长久之计,故用正则*
来匹配每次版本更新而变化的版本号。
※ 6环节③拓展:该方式并不推荐在实际生产环境中使用,一是会导致镜像文件体积变大,二是如果是一些国外的代码仓库会存在拉取失败或拉取慢的情况。一般建议结合代码仓库自身携带的CI
控制台或结合云厂商的流水线,也可以通过Jenkins
。
※ 6环节④拓展:Dockerfile
文件推荐放在项目的根目录下,这样方便在脑中形成一个清晰的项目上下文结构,Dockerfile
文件的位置变动涉及到该文件中每项命令的变动,比如我们将该项目的Dockerfile
文件放到一个新建的目录df
下,对应ADD
、COPY
的命令都需要变动,及从ADD ./pom.xml pom.xml
变为ADD ../pom.xml pom.xml
☆ 参考文献: \
◎ 文中所用到的资源链接: \
¤ LaoCat的Github:
https://github.com/Blackcat308