Docker部署jar
实现功能
- 部署springboot下发布的jar包
- 不同docker容器之间通信(如MySQL访问、Redis访问)
- 多个jar包部署
参考文献
Just a moment…
Just a moment…
https://www.jb51.net/article/279449.htm
springboot配置
这里使用多yaml配置文件,这样子我们在服务端就可以使用java -jar
时附带参数来选择性的使用对应的配置文件
注意,下面三个文件所有内容都必须是完整的!也就是说我们后续是直接选择其中的一个配置文件进行启动,不会用到其他剩下的几个配置文件!!!
- application:默认配置文件,我们进行本地调试的时候使用,MySQL地址直接写localhost
- application-dev:这个不要管,我随便写的
- application-pro:生产环境配置文件,MySQL地址写桥接对象容器的地址,我这里使用的是我开启的MySQL容器名
mysql8
(这里后续会讲解为什么这么做)
application.yaml
server:port: 10085spring:datasource:url: jdbc:mysql://172.18.0.2:3306/esp?characterEncoding=utf-8&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 100minimum-idle: 10
# swagger基本配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'packages-to-scan: io.zhiller.zercardpacket.controller
# knife4j的增强配置,不需要增强可以不配
knife4j:enable: truesetting:language: zh_cn
application-pro.yaml
server:port: 10085spring:datasource:url: jdbc:mysql://mysql8:3306/esp?characterEncoding=utf-8&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 100minimum-idle: 10
# swagger基本配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'packages-to-scan: io.zhiller.zercardpacket.controller
# knife4j的增强配置,不需要增强可以不配
knife4j:enable: truesetting:language: zh_cn
之后按照顺序依次点击maven对应生命周期指令,在我们每次修改代码后要上传到服务器时,都必须完整的再走一遍这个步骤!!!
之后你就会在项目根目录下的target文件夹内找到编译好的jar包;
我这里把jar包命名为 zer-backend.jar
特别注意,这里还需要我们删去一些内容
打开pom.xml
在mainClass标签下有一个skip标签,必须把它删掉,不然我们切换不同配置文件的时候会直接拒绝并报错;
下图展示的是删除过后的pom.xml文件
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>io.zhiller.zercardpacket.ZerCardPacketApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
创建MySQL容器
我的springboot上使用的mysql-connect-j版本是8的,所以我这边也直接使用mysql:latest
镜像,也就是最新的MySQL8镜像;
拉取镜像:docker pull mysql:latest
构建MySQL容器:docker run -d -p 10085:10085 --name mysql8 -e MYSQL_ROOT_PASSWORD mysql:latest
此时注意要在服务器的安全组策略内允许3306端口访问;
之后你可以通过navicat连接到MySQL,然后添加对应数据库和表啥的(这里不演示)
配置桥接网络
由于我们使用docker同时部署了springboot的jar包以及MySQL,那么两个容器之间实际上是相互隔离的,我们只能通过docker给出的桥接方式把两个容器通过桥接网络连接起来,这样子springboot才可以连接到对应容器内的MySQL;
举例:对于连接到同一个docker桥接网络下的两个容器d1
和d2
- 可以直接通过各自在桥接网下的IP联通,如
ping 172.18.0.2
- 或者直接使用对应容器名联通,如
ping d1
首先看一下当前有哪些桥接网络:docker network ls
我这里之前创建了一个桥接网络esp-network
,我们可以执行以下指令创建对应桥接网络 docker network create [网络名字]
把对应容器添加到桥接网络的方式有两种,我们使用第二种方式关联桥接网络
- 在容器创建时添加(不推荐)
- 容器创建后通过指令关联(推荐,自由度更高)
把创建好的MySQL容器添加到桥接网络内:
docker network connect esp-network mysql8
构建docker镜像
这里我使用mobaxterm链接到云服务器,建议大家也下载一个这个软件,他比啥xshell好使多了,而且还免费!!!
随便选择一个空文件夹,我这里有三个文件
dockerfile
用于构建对应jar包的镜像文件espbk-shell.sh
偷懒专用,全自动镜像创建、运行、桥接网络所有步骤,便于后续快速更新镜像zer-backend.jar
我们刚刚打包好的jar包
dockerfile
# 我的springboot编译时使用JDK1.8,所以这里搭设openjdk:8环境
FROM openjdk:8# 设置容器所有者
MAINTAINER zhiller# 把当前文件夹下的jar包添加到容器内
ADD ./zer-backend.jar backend.jar# 这是正常的,不带参数的启动方式
# CMD ["java","-jar","backend.jar"]# 因为我们需要使用生产环境,所以使用参数spring.profiles.active开启
# spring.profiles.active是全量覆盖,也就是说只会启用这一个配置文件,不会管其他的配置文件
CMD ["java","-jar","backend.jar","--spring.profiles.active=pro"]
espbk-shell.sh
#!/bin/bashcontainer_name="espbk" # 容器名
container_port="10085" # 容器运行端口
image_name="espbk" # 镜像名
image_tag="1.0" # 镜像tag(一般我们使用latest,这里我用1.0)
dockerfile_name="dockerfile" # dockerfile的文件名
network="esp-network" # 桥接网络的名称echo "正在停止并删除docker镜像"docker rm -f ${container_name}docker image rm ${image_name}:${image_tag}echo "正则重新更新当前镜像"docker build -f ./${dockerfile_name} -t ${image_name}:${image_tag} .docker run -d -p ${container_port}:${container_port} --name ${container_name} ${image_name}:${image_tag}docker network connect ${network} ${container_name}echo "大功告成!您可以查看已经更新的镜像了!!!"
这样子,我们可以直接运行脚本实现部署:bash espbk-shell.sh
最后,把我们构建好的jar包容器添加到桥接网络:docker network connect esp-network espbk
最后监视一下我们的桥接网络,确认MySQL和jar包容器都在同一个桥接网络下
docker network inspect esp-network
找到container字段,里面就包含了该桥接网络下存在的容器
不难发现,MySQL使用172.18.0.2
,而我们的jar包使用172.18.0.3
网络调试
由于我们使用dockerfile构建jar包镜像是,使用的底层镜像是openjdk,他不带基本的linux指令(也就是说没有ping、netstat这些关键指令)
我们可以曲线救国,使用主机自带的指令直接操控容器
具体可参考文献:docker容器内缺少命令的简单解决办法_docker_脚本之家
首先安装依赖(我使用ubuntu):apt-get install -y util-linux
之后使用管道函数,过滤出我们正在运行的jar包容器:docker ps | grep espbk
复制容器的长ID(划红线处)
根据容器ID获取容器的PID:docker inspect --format "{{ .State.Pid }}" 2877e2947850
之后就可以愉快的使用nsenter指令来操控容器了:nsenter -t 3873441 -n ifconfig