【Linux】使用Jenkins和Docker集成部署SpringBoot应用

[TOC]

一、Jenkins介绍

来自官网 的介绍:

作为一个可扩展的自动化服务器,Jenkins 可以用作简单的 CI 服务器,或者变成任何项目的持续交付中心。

我的理解:

可以将代码从SVN或GIT仓库拉取过来进行自动编译与发布,所以可以成为一个交付中心,也可以作为一个集成测试环境。

二、前置准备

2.1服务器(Linux)所需环境

1
2
3
4
5
6
7
OS:CentOS7 (买的百度云学生服务器
Jenkins
Docker
Jdk
Maven
SVN
Git(从github拉取代码所需)

Jdk&Maven安装点这
Docker 安装点这
SVN 安装使用点这

2.2配置Docker工作空间

1
2
3
4
5
#创建文件夹用来放docker工作空间
mkdir /home/work/demo
cd /home/work/demo
#创建备份文件夹
mkdir backup

然后添加Docker构造文件

1
vim Dockerfile

在文件中添加如下内容

1
2
3
4
5
6
7
#基于openjdk:8
FROM openjdk:8
#这里其他的项目,可以把demo改成其他的项目名称
ADD demo-1.0-SNAPSHOT.jar demo.jar
RUN bash -c 'touch /demo.jar'

ENTRYPOINT ["java","-jar","/demo.jar"]

添加shell脚本文件

1
vim run.sh

添加如下内容

1
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#定义好这些变量,后面其他的项目,只需要改前面这些变量即可
PROJECT_NAME=JenkinsDemo #Maven项目名称
IMAGE_NAME=demo #生成的镜像名称
BASE_PATH=/home/work/demo #Docker工作空间
PORT=9120 #端口
TASK_NAME=Jenkins # 任务名称
SOURCE_PATH=/var/lib/jenkins/workspace/$TASK_NAME/target/ # Jenkins生成jar包位置
#查看当前docker是否运行了该项目
CID=$(docker ps | grep "$IMAGE_NAME" | awk '{print $1}')

DATE=`date +%Y%m%d%H%M`

# 将jar包移动到工作空间
function transfer(){
echo "newest $SOURCE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar moveto $BASE_PATH ...."
sudo cp $SOURCE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar $BASE_PATH/$IMAGE_NAME-1.0-SNAPSHOT.jar
echo "move complete"
}

# 备份
function backup(){
if [ -f "$BASE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar" ]; then
echo "$PROJECT_NAME-1.0-SNAPSHOT.jar 开始备份"
sudo cp $BASE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar $BASE_PATH/backup/$PROJECT_NAME-$DATE.jar
sleep 3
sudo rm -rf $BASE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar
echo "备份完成"
else
echo "$BASE_PATH/$PROJECT_NAME-1.0-SNAPSHOT.jar not exists , pass "
fi
}

#构建镜像
function build(){
echo "开始构建"
cd $BASE_PATH
sudo docker build -t $IMAGE_NAME .
}

#运行
function run(){
backup
transfer
build
if [ -n "$CID" ]; then
echo "存在,删除再运行"
sudo docker stop $CID
sudo docker rm $CID
sudo docker run -d -p $PORT:$PORT $IMAGE_NAME
echo "complete"
else
echo "不存在,直接运行"
sudo docker run -d -p $PORT:$PORT $IMAGE_NAME
echo "create ok"
fi
}

#执行run方法
run

三、 安装Jenkins

3.1 官网安装步骤如下:

1
2
3
4
5
6
7
8
#添加jenkins 源
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo

#导入key
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key

#安装
yum install jenkins

jenkinsdown
不过通过yum安装的效果会比较慢,极端前端下仅几k的速度,因此可以把rpm包先下过来,然后通过rpm的方式安装

3.2 rpm方式安装如下:

  • 首先下载rpm包,可从清华镜像下载,也可以从某云提取码w6tl下载
  • 将rpm包上传至centos 中
  • 执行rpm -ivh jenkins-2.204.2-1.1.noarch.rpm 这个文件

3.3 启动jenkins

1
service jenkins start

如果是自己安装的jdk,Jenkins第一次启动可能会报错,可以使用命令systemctl status jenkins.server来查看错误明细,可以看到错误信息提示java: no such file or directory

Jenkinsfail

执行如下命令:vim /etc/init.d/jenkins

candidates里面加上自己安装的jdk的java命令的位置,如下

changejava

然后重新加载配置文件systemctl daemon-reload后重启Jenkins

1
service jenkins start

成功执行有如下提示

1
2
[root@instance-7k1d5qb8 ~]# service jenkins start 
Starting jenkins (via systemctl): [ OK ]

四、 访问Jenkins

在浏览器打开地址http://服务器ip:8080 ,不出意外就能进入到如下界面,然后根据提示输入密码:

inputse

输入密码之后会进入到如下界面,选择推荐的插件即可,就会进入到插件安装页面。

installplug

如若网络不好的情况下,可能会出现如下情况,安装插件失败

installplugerror

  • 解决方法(1)如下

打开 http://ip:8080/pluginManager/advanced

最后站点设置

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

然后保存

changesite

然后systemctl daemon-reload 使配置生效,并重启Jenkins systemctl restart jenkins

访问Jenkins出现的问题:

openjenkinserror

可能是由于自己按照的jdk,少了一些基础程序,如下安装,重启即可:

1
sudo yum install libgcc.i686 --setopt=protected_multilib=false

五、配置Jenkins

插件安装成功之后会进入到如下界面,创建一个用户即可

createuser

使用账号密码登陆之后需要进行一些基础配置:

gotoconfig
选择全局工具配置
configjdk
此处主要配置maven、jdk、docker 三者配置相似,把自动安装的勾取消,便可以输入在系统中的位置。查看环境变量中位置如下:

getjdkmavenpath

而yum所安装的docker 位置如下:

1
/var/lib/docker

六、创建SpringBoot项目

新建一个maven项目,项目名为JenkinsDemo 项目名在后续会用到

pom依赖和插件如下

1
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
30
31
32
33
34
35
36
37
38
39
40
41
42
<parent>
<artifactId>spring-boot-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.1.7.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<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>
</configuration>
</plugin>
</plugins>
</build>

application.yml 修改端口,默认8080会和Jenkins冲突,除非修改了Jenkins的端口

1
2
server:
port: 9120

Controller类

1
2
3
4
5
6
7
8
9
@RestController
public class HelloController {

@RequestMapping("/test")
public String hello(){
return "自动构建测试" + LocalDateTime.now();
}

}

启动类

1
2
3
4
5
6
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class,args);
}
}

项目基础结构搭建完成之后。

6.1 添加SVN控制

addsvn

sharesvn

添加完版本控制之后,底端会有一个Version Control ,右键选择commit

commit

勾选需要提交的文件夹或文件

shouldcommit

提交完成之后,可以在svn管理软件中看到,此处使用小乌龟
insvn

七、新建任务

newtask
输入名称Jenkins,选择构建一个自由风格的软件项目 确定,便进入到如下配置
general
勾选这个,以免产生过多的文件,导致服务器资源耗竭
srouce
添加svn,Jenkins会从这获取源码
creatauth
svn当然需要添加账号密码
chufaqi
触发器,大概就是何时会进行构建,如若是变化不频繁的,可以不选,手动构建
goujianghuanjing
这里仍然是删除之前的工作空间,避免代码冲突
goujiangxuanzemaven
因为我们的是Maven项目,所以选择Maven构建
mavenconfig
Maven构建配置如上。配置文件也可以指定位置,最好指定修改了国内镜像的settings.xml 文件
execshell
后面选择执行shell脚本

1
2
3
4
#!/bin/bash
cd /home/work/demo

sudo ./run.sh

最后确定

7.1 构建查看输出

项目构建成功首页如下所示,点击名称Jenkins查看该任务详情

task

里面的工作空间存放了从svn拉取的代码,下面的Build History 就是每次构建的记录

detail

这里是看工作空间的代码workspace

点击Build History里面的某一项记录,可以进入到这里,然后点击控制台输出可以查看代码运行情况。

selectConsole

第一次运行输出往往会需要从maven下载各种依赖,如果比较慢的话,是否需要切换为国内镜像。

下图的红圈中,

第一部分表示Maven install 已经ok了 ;

第二部分是开始执行shell命令 ;

第三部分是执行Dockerfile 命令。

如果在那个部分出了问题导致访问失败,可以对应排除。

console

如果一路顺利,⑧出意外的话,执行

1
docker ps

便可以看到如下输出,表示该demo已经运行完成。

runsuccess

然后我们只需要在浏览器输入

1
http://ip:9120/test

便可以看到如下输出。然事与愿违,这个过程构建了好几次才搞定。后面有参考

webok

7.2 构建遇见的问题

  1. sudo: ./run.sh: command not found ,因为刚刚创建的run.sh文件没有赋予可执行权限

    ​ 在/home/work/demo 目录下执行如下命令

    1
    chmod a+x run.sh

    添加可执行权限

  2. 各种no such directory , 根据控制台输出提示的部分,然后查看是哪个文件配置出错,然后处理

  3. sudo: no tty present and no askpass program specified 因为在shell文件中有sudo命令,但是权限又不够。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #在Jenkins宿主服务器上运行如下命令
    $ sudo visudo
    #在文件的末尾加上一行
    jenkins ALL=(ALL) NOPASSWD: ALL
    #保存文件(注意保存的时候修改文件名,文件名后缀不要加上默认的.tmp,即可覆盖原文件)
    Ctrl+O
    #退出编辑
    Ctrl+X
    #重启Jenkins服务
    /etc/init.d/jenkins restart
  1. Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

    ​ 重启docker 即可 systemctl restart docker

八、更新迭代

在Controller中添加如下代码:

1
2
3
4
@GetMapping("/new")
public String newMethod(){
return "version 2";
}

然后提交到svn

svncommit

稍等一会待Jenkins自动构建

然后在浏览器地址中输入http://ip:9120/new,不出意外便能出现一下结果。如果无:

  1. 查看是否产生了构建,若无,点击立即构建手动
  2. 查看构建记录中的控制台输出,根据不同的提示,解决不同的问题。

version2

九、总结

这仅是Jenkins的简单使用,还有更过的高级用法暂未用到,学习记录倒是够了。

1.这里用Jenkins做了什么?

​ 本地敲代码 -》 提交到SVN -》 Jenkins自动编译部署 -》访问网页

2.Jenkins几个配置

​ 全局配置: Jdk、Maven、Docker

​ 任务配置: 代码源,如何构建