SpringBoot3项目构建Docker镜像记录帖

一、环境

  • Java版本:JDK-21
  • SpringBoot版本:SpringBoot-3.2.1
  • Docker版本:Docker-24.0.7

二、流程

1.使用Maven将SpringBoot项目打包成Jar包

在项目根目录下执行mvn clean package,则会在项目根目录的target文件夹下生成Jar包。

2.编写Dockerfile

本项目的Dockerfile主要包含以下命令:FROM, LABEL, COPY, EXPOSE, CMD

FROM amazoncorretto:21

LABEL author="LibraStalker"
LABEL version="1.0"
LABEL description="SmartTourism项目,当前版本包含查询景点列表的接口"

COPY . /applications/smart-tourism/

EXPOSE 18180

CMD java -jar /applications/smart-tourism/smart-tourism-0.0.1-SNAPSHOT.jar --spring.config.location=/applications/smart-tourism/conf/application.yml

2.1 FROM命令

FROM命令指定一个镜像作为构建自定义镜像的基础镜像,在这个基础镜像之上进行修改定制,这个指令也必须是Dockerfile的第一条指令。
由于我的是Java项目,因此应该到DockerHub官网找到Java环境的基础镜像,首先在DockerHub上搜索java,发现java的官方基础镜像已经停止维护,应该调整为openjdk镜像,
在这里插入图片描述
然后搜索openjdk官方镜像,发现openjdk镜像也被弃用了,

在这里插入图片描述
于是按官方的指引,找到amazoncorretto官方镜像,
在这里插入图片描述
然后再Tags选项栏中搜索21,找到需要的jdk-21的基础镜像
在这里插入图片描述
这里将使用amazoncorretto:21作为基础镜像,Dockerfile命令为FROM amazoncorretto:21
在这里插入图片描述

2.2 LABEL命令

Label命令使用键值对的方式定义一些元数据信息,比如作者、版本、关于镜像的描述信息。

2.3 COPY命令

COPY命令有以下两种语法形式:

  • COPY <源路径>... <目标路径>
  • COPY ["<源路径1>",... "<目标路径>"]

COPY命令主要用于将宿主机内的源路径的内容,复制到容器的目标路径中。

COPY命令和ADD命令的区别

COPY命令和ADD命令都能将文件从宿主机复制到容器,ADD命令支持自动解压缩,但是ADD命令会使构建镜像时的缓存失效,导致构建镜像的速度比较慢,官方推荐使用COPY进行文件复制,在需要自动解压缩的场景可以使用ADD命令。

2.4 EXPOSE命令

EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。

2.5 CMD命令

CMD指令用于指定默认的容器主进程的启动命令的,Dockerfile中只能有一条CMD指令,如果有多条CMD指令,则只有最后一个CMD会生效。
CMD指令有以下两种语法格式:

  • shell格式:CMD <命令>
  • exec格式:CMD ["可执行文件", "参数1", "参数2"...]
    exec格式需要明确指定shell路径,否则变量可能不会生效。
CMD命令和RUN命令的区别

Docker中每一条命令都会建立一层镜像,RUN命令也是会在前面命令构建的镜像的基础上构建新的一层镜像,RUN命令实际上是运行一个命令并提交结果,可以有多条RUN命令,而CMD命令在构建时不执行任何操作,只是指定容器运行时的默认命令,且只有最后一条CMD命令生效。

CMD命令和ENTRYPOINT命令的区别

ENTRYPOINT命令和CMD命令一样,都是指定容器的启动程序及参数,ENTRYPOINT在运行时也可以被替代,但是需要通过docker run的参数--entrypoint来指定替代的命令。
如果没有指定--entrypointdocker run跟在镜像名后面的是command,运行时会替换CMD的默认值,而对于ENTRYPOINT来说是添加在ENTRYPOINT后面的参数。
ENTRYPOINT指令不会被RUN指令覆盖,而CMD指令会被RUN指令覆盖。

2.6 VOLUME命令

VOLUME命令在容器内声明一个位置作为匿名卷,容器中在该位置产生的数据都会持久化到主机中,从而避免容器删除后数据丢失,这个匿名卷可以被其他容器共享,匿名卷是在Docker宿主机的默认目录创建的。
​docker run -v 主机目录:容器目录中的-v命令是指定容器内的一个位置跟主机的一个位置共享数据,容器内在该位置产生的数据都会持久化到主机目录的对应位置,所以-v命令可以说是创建了一个具名卷,这个卷在主机上的位置由用户指定,VOLUME命令创建一个匿名卷,匿名卷在主机的位置是Docker的默认目录。

3.构建Docker镜像

docker build -t <镜像名>:<标签名> .会使用当前目录的Dockerfile文件构建镜像,如果要指定Dockerfile文件,可以使用docker build -f <dockerfile文件位置> -t <镜像名>:<标签名> .来构建,注意构建命令最后的.表示在当前目录构建镜像,不能漏掉。
如果构建镜像过程下载镜像很慢,可以先使用docker pull命令将镜像拉取到本地,构建时会更快一些,但这样本机镜像也会存在拉取下来的镜像了,构建完镜像后可以使用docker images命令查看本机的镜像。

4.运行Docker容器

构建好Docker镜像后,应该使用docker create命令创建容器,然后使用docker start命令启动容器,而docker run命令是两者的结合,在创建容器后同时启动容器,参考命令如下:

docker run -d --name <容器名称> -p <主机端口>:<容器端口> -v <主机目录>:<容器目录> <镜像名>:<标签名>

常用参数解释:

  • --name:指定容器名称
  • -d:指定容器以后台方式启动
  • -p:指定容器和主机的端口映射
  • -v:指定容器和主机的目录映射
  • -it:指定以交互方式运行容器
  • -rm:指定容器退出后立即删除容器

三、问题

1.SpringBoot项目在容器中运行报错Springboot Failed to start bean 'webServerStartStop

SpringBoot项目打包的Jar包在宿主机上运行正常,但是在容器内就报Springboot Failed to start bean 'webServerStartStop的错误,出现这个错误一般是项目的端口或ip出现问题,而端口问题一般是端口被占用导致项目无法启动,但是我排查了端口没有占用,最后发现我在SpringBoot项目的配置文件中设置了监听ipv6地址"::",而Docker引擎默认是不开启ipv6的,需要自己配置ipv6,然后创建ipv6的网络,再使用ipv6的网络运行容器,觉得比较麻烦就修改监听ipv4地址了。

2.Docker容器内的项目怎么访问宿主机上部署的服务

方式一:在docker run时添加参数--add-host host.docker.internal:host-gateway,此后在容器中就可以使用host.docker.internal作为宿主机的别名来访问宿主机上面的服务了。
方式二:使用默认桥接模式访问主机,大多数Docker引擎会将主机表示为默认docker0桥接网络上的172.17.0.1,因此可以使用172.17.0.1来访问宿主机上面的服务。

四、参考

1.Dockerfile相关

https://zhuanlan.zhihu.com/p/114033550
https://blog.csdn.net/lixuankuan/article/details/119643508
https://blog.csdn.net/wucong60/article/details/83993922
https://blog.51cto.com/u_15344989/4374515
https://docs.docker.com/engine/reference/builder/

2.Docker容器相关

https://blog.csdn.net/ruoshuiyx/article/details/128325694
https://blog.csdn.net/jcmj123456/article/details/131692252
https://blog.csdn.net/taiyangdao/article/details/83066009
https://www.cnblogs.com/1446358788-qq/articles/14071650.html

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值