Skip to content

Jenkins教程 - 7 部署SpringBoot到docker容器中 ​

现在使用 Jenkin 来部署 SpringBoot 项目,将项目部署到 Docker 容器中。

这里为了保持本章内容的独立性,之前已经配置的步骤,也重新复制了过来,如果你从前面看过来的,就当重新温习了一遍,我将之前的构建任务删掉了,重新创建了一遍。

7.1 准备SpringBoot项目 ​

1 新建一个SpringBoot 项目 ​

新建一个 SpringBoot 项目,这里我就在 SpringBoot 中新建一个 Controller。

只提供了一个接口,证明 SpringBoot 能访问运行就好了。

java
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";
    }

}

同时在项目下创建一个 docker 文件夹,并编写 Dockerfile 文件,后面用来生成 Docker 镜像。

Dockerfile 文件内容如下:

shell
# 使用基础的 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"]

项目结构如下:

这里还有一个 deploy.sh ,用来执行停止、删除、启动容器等操作,后面介绍。

2 将SpringBoot项目托管码云 ​

Jenkins 服务后面需要从 git 仓库拉取代码进行构建,这里使用 gitee 码云来托管代码,所以这里将 SpringBoot 项目托管到码云。

这里细节就不介绍了,git 不太会的,可以学习本站的 git教程 。

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,如下:

shell
#!/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

deploy.sh 主要是构建镜像,并停止和删除之前的镜像,运行新的镜像。

2 重新构建 ​

除了可以点击 Dashboard 页面,任务列表后面的构建按钮,可以构建。


还可以在任务详情页面,点击 立即构建 按钮。


在 Jekins 的控制台页面,可以查看构建日志:

可以看到是否构建和传输成功,根据提示信息修改即可,如果传输成功,运行不成功,可以查看业务服务器上 jar 包有没有传输到对应的目录。

在 Post Steps 的 Send files or execute commands over SSH 的高级中,有一个 Exec timeout 选项,表示执行超时时间,默认是2分钟,如果任务构建时间比较长,可以将时间设置的长一些。

3 访问SpringBoot项目 ​

访问 SpringBoot 项目测试的接口,发现可以访问。

重新修改代码,并推送到 gitee,然后重新使用 Jekins 重新执行构建,发现自动构建更新完成。

至此,完成了整个 SpringBoot 项目的自动构建。

内容未完......