# Jenkins教程 - 7 部署SpringBoot到docker容器中
现在使用 Jenkin 来部署 SpringBoot 项目,将项目部署到 Docker 容器中。
这里为了保持本章内容的独立性,之前已经配置的步骤,也重新复制了过来,如果你从前面看过来的,就当重新温习了一遍,我将之前的构建任务删掉了,重新创建了一遍。
# 7.1 准备SpringBoot项目
# 1 新建一个SpringBoot 项目
新建一个 SpringBoot 项目,这里我就在 SpringBoot 中新建一个 Controller。
只提供了一个接口,证明 SpringBoot 能访问运行就好了。
package com.doubibiji.hellospringboot.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello www.doubibiji.com";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
同时在项目下创建一个 docker
文件夹,并编写 Dockerfile
文件,后面用来生成 Docker
镜像。
Dockerfile
文件内容如下:
# 使用基础的 Java 11镜像
FROM openjdk:11
# 对外暴露的端口
EXPOSE 9000
# 设置环境变量来指定时区
ENV TZ=Asia/Shanghai
# 将时区文件复制到容器中的特定路径
RUN ln -sf /usr/share/zoneinfo/{TZ} /etc/localtime && echo "{TZ}" > /etc/timezone
# 将jar包添加到容器中并更名为app.jar
ADD hello-springboot-0.0.1-SNAPSHOT.jar app.jar
# 运行jar包
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
项目结构如下:
这里还有一个 deploy.sh ,用来执行停止、删除、启动容器等操作,后面介绍。
# 2 将SpringBoot项目托管码云
Jenkins 服务后面需要从 git 仓库拉取代码进行构建,这里使用 gitee 码云来托管代码,所以这里将 SpringBoot 项目托管到码云。
这里细节就不介绍了,git 不太会的,可以学习本站的 git教程 (opens new window) 。
# 7.2 配置插件和工具
# 1 安装Maven插件
我们现在构建项目需要使用 Maven,所以还需要安装一个 Maven 插件。
在可用的插件中,搜索 maven,在搜索结果中选中 Maven Integration
进行安装。
拉到最下面,查看安装进度
# 2 配置Maven工具
我们的自动化构建任务是使用 Maven 构建的,需要告诉 Jenkins Maven的安装位置。
配置 Maven 的路径:
使用 mvn -v
可以查看 maven 安装的路径。
# 3 安装SSH插件
这个插件的作用就是将 Jenkins 构建的 SpringBoot 项目的 jar 包发布的业务服务器上。
还是刚才安装插件的步骤:
# 4 配置业务服务器
后面需要将构建的 SpringBoot 的 jar 包发布到业务服务器,所以在这里配置一下要发布到的业务服务器的信息。
我也不知道选项为啥突然变成中文了,就是之前的 Manage Jenkins
下的 System
。
拉到最下面找到 Publish over SSH
,安装完 SSH 插件才有这个选项。
Server是可以有多个的,新增一个 SSH Server。
配置上面几个选项就可以了,配置完成,在最下面有个测试的按钮,可以测试一下配置有没有问题,没有问题,保存配置。
# 7.3 创建构建任务
# 1 新建任务
在 Jenkins 管理页面,新建Item,也就是新建构建任务。
填写任务名称:
# 2 源码管理
分支配置:
# 3 构建配置
上面使用默认配置即可。
- Pre Steps :表示构建前的工作,例如要执行一些脚本,这里我们不需要;
- Post Steps :表示构建后的工作;
- Root POM :指定构建使用的 pom.xml,这里表示在远程仓库的根目录下,如果远程仓库中,pom.xml不在根目录下,例如在 demo 目录下,则这里需要配置
demo/pom.xml
。
# 7.4 执行构建
任务创建了,先不部署到docker服务器,先测试一下能不能构建成功。点击任务后面的按钮,手动执行构建。
执行后,在构建执行状态列表,可以看到构建的进度。
可以点击进去查看构建的控制台信息:
如果已经构建完成,也可以点击任务进入任务信息页面,查看构建失败的原因:
摸索一下页面的功能就好了。
第一次构建需要的时间可能比较久,因为要下载很多项目依赖的 jar 包。
构建如果成功,会显示成功,并在 jenkins
的工作空间下构建出 SpringBoot 项目的 jar 包。
如果没有成功,可以看一下日志,失败的原因是什么。
# 7.5 部署到业务服务器
上面的步骤只是在 Jenkins 服务器上生成了 jar 包,还没有一条龙执行到自动部署到业务服务器的 Docker 容器中。下面继续。
# 1 配置传输
重新进入到构建任务的配置页面,对 Post Steps
进行配置,也就是构建后的操作。
选择 Send files or execute commands over SSH
。
因为 Jenkins 服务和 业务服务不是在同一个服务器上,所以才使用 Send files or execute commands over SSH
,如果在一台服务器 上,直接选择 执行 shell
就可以了,都不用将文件推送到别的服务器,直接使用shell命令 mv
去移动文件就可以了。
这里传输三个文件,一个 jar包、Dockerfile文件、执行发布的脚本文件,脚本文件也通过 Jenkins 传到业务服务器上,主要负责打包镜像,停止并删除之前的容器,启动当前的容器。
在构建任务的 Post Steps 的SSH Server填写如下配置:
SSH Server:选择要传输的业务服务器。
Source files :在 Jenkins 服务器上,构建的 jar 包在 Jenkins 的工作空间下,也就
~/.jenkins/workspace
,我这里构建的任务名称叫hello-jenkins
,所以 jar 包的地址是/home/doubi/.jenkins/workspace/hello-jenkins/target/hello-springboot-0.0.1-SNAPSHOT.jar
。这里填写的地址是从构建的任务所在的文件夹开始算的,也就是/home/doubi/.jenkins/workspace/hello-jenkins
算起,所以这里我填写了target/*.jar
,使用了通配符,表示target
目录下所有的 jar 包。Remote directory :表示传输到的远程服务器的路径,也是从家目录
~
开始算起,表示传输到~/projects/hello-springboot
目录下,也就是传输到/home/doubi/projects/hello-springboot
目录下,则传输完成,在业务服务器上 jar 包的路径是/home/doubi/projects/hello-springboot/hello-springboot-0.0.1-SNAPSHOT.jar
,如果路径不存在,会自动创建。Remove prefix :这个表示删除的路径的前缀,如果不填写,则复制到远程后,会将
target
目录一起复制,会变成/home/doubi/projects/hello-springboot/target/hello-springboot-0.0.1-SNAPSHOT.jar
,这里将target
路径删掉。Exec command :表示上传完成执行的命令。
再添加一个传输配置,将 Dockerfile 和 deploy.sh 也传输到业务服务器。
Dockerfile 在准备 SpringBoot 的时候已经看到脚本了。
下面编写一下 deploy.sh
,如下:
#!/bin/bash
# 项目名称
projectName=hello-springboot
# 年月日时分的时间戳
timestamp=$(date +%Y%m%d%H%M)
# 新镜像的名称
newImageName=$projectName-$timestamp
# 1.首先使用Dockerfile打镜像
docker build -t $newImageName .
# 2.停止并删除之前运行的容器
runningContainerId=$(docker ps | grep "$projectName" | awk '{print $1}')
# 如果有运行中的容器,停止它,并删除它
if [ -n "$runningContainerId" ]; then
docker stop "$runningContainerId"
docker rm "$runningContainerId"
fi
# 万一新的镜像有问题,为了恢复,就不删除之前的镜像了
# 在宿主机上创建logs目录,用于容器挂载,这样查看日志可以直接在宿主机查看,比较方便
mkdir -p ~/projects/$projectName/logs
# 3.运行新的镜像
docker run -d -p 9000:9000 --restart=always -v ~/projects/$projectName/logs:/logs $newImageName
# 运行的时候可以指定application-*.yaml配置文件,例如指定测试环境
# docker run -d -e SPRING_PROFILES_ACTIVE=test -p 9000:9000 --restart=always -v ~/projects/$projectName/logs:/logs $newImageName
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
deploy.sh
主要是构建镜像,并停止和删除之前的镜像,运行新的镜像。
# 2 重新构建
除了可以点击 Dashboard 页面,任务列表后面的构建按钮,可以构建。
还可以在任务详情页面,点击 立即构建
按钮。
在 Jekins 的控制台页面,可以查看构建日志:
可以看到是否构建和传输成功,根据提示信息修改即可,如果传输成功,运行不成功,可以查看业务服务器上 jar 包有没有传输到对应的目录。
在 Post Steps
的 Send files or execute commands over SSH
的高级中,有一个 Exec timeout
选项,表示执行超时时间,默认是2分钟,如果任务构建时间比较长,可以将时间设置的长一些。
# 3 访问SpringBoot项目
访问 SpringBoot 项目测试的接口,发现可以访问。
重新修改代码,并推送到 gitee,然后重新使用 Jekins 重新执行构建,发现自动构建更新完成。
至此,完成了整个 SpringBoot 项目的自动构建。