SpringBoot + Gitee + Jenkins + Docker 持续集成

 

​​​​​​1.拉取Jenkins镜像

docker pull jenkinsci/blueocean

官方推荐使用这个镜像,https://www.jenkins.io/zh/doc/book/installing/

2.启动Jenkins

 docker run -u root -d --name jenkins -p 8081:8080 -v /data/jenkins_home:/var/jenkins_home jenkinsci/blueocean

备注:

备注: -d //启动在后台

--name //容器名字

-p //端口映射(8081:宿主机端口,8080:容器内部端口)

-v //数据卷挂载映射(/data/jenkins_home:宿主机目录,/var/jenkins_home:容器目录)

jenkinsci/blueocean //第一步拉取的镜像名

3.访问Jenkins并下载插件

地址:http://localhost:8081

端口号由你启动Jenkins的时候决定

这个文件是在Docker容器里面,不是在宿主机里面。但因为宿主机把/data/jenkins_home映射到容器的/var/jenkins_home,所以在宿主机应该这样访问, cat /data/jenkins_home/secrets/initialAdminPassword(第2步启动的时候指定了映射路径)

设置自己的账号密码,邮箱我是随便填的

点击按钮重启之后

 

4.汉化

如果页面长时间没反应可以刷新页面,刷新之后如果跳到主页面说明安装成功,如果没有就在等一下。

 

成功!!!

 

5.安装插件

安装gitee

这个安装很慢,需要耐心等待

 

6.配置Maven、JDK

jdk的版本建议使用8,在构建的时候会自动从官网下载JDK。所以需要你提供Oracle的账号密码,不然在构建的时候无法下载JDK就会出错。

 

 

7.Maven换源

把下面的文件放到/data/jenkins_home/.m2/settings.xml,其实路径可以随意,但是Docker里面的Jenkins必须找得到。

如果不嫌中央仓库慢的话,可以不用换源。

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <usePluginRegistry/>
  <offline/>
  <pluginGroups/>
  <servers/>
  <mirrors>
    <mirror>
     <id>aliyunmaven</id>
     <mirrorOf>central</mirrorOf>
     <name>阿里云公共仓库</name>
     <url>https://maven.aliyun.com/repository/central</url>
    </mirror>
    <mirror>
      <id>repo1</id>
      <mirrorOf>central</mirrorOf>
      <name>central repo</name>
      <url>http://repo1.maven.org/maven2/</url>
    </mirror>
    <mirror>
     <id>aliyunmaven</id>
     <mirrorOf>apache snapshots</mirrorOf>
     <name>阿里云阿帕奇仓库</name>
     <url>https://maven.aliyun.com/repository/apache-snapshots</url>
    </mirror>
  </mirrors>
  <proxies/>
  <activeProfiles/>
  <profiles>
    <profile>  
        <repositories>
           <repository>
                <id>aliyunmaven</id>
                <name>aliyunmaven</name>
                <url>https://maven.aliyun.com/repository/public</url>
                <layout>default</layout>
                <releases>
                        <enabled>true</enabled>
                </releases>
                <snapshots>
                        <enabled>true</enabled>
                </snapshots>
            </repository>
            <repository>
                <id>MavenCentral</id>
                <url>http://repo1.maven.org/maven2/</url>
            </repository>
            <repository>
                <id>aliyunmavenApache</id>
                <url>https://maven.aliyun.com/repository/apache-snapshots</url>
            </repository>
        </repositories>             
     </profile>
  </profiles>
</settings>

 

这里要注意一下路径,宿主机的路径和容器里面的路径不一样

 

8.配置Gitee仓库信息

 

9.配置SSH连接

这里我解释一下为什么需要用到SSH,Docker里面的一个容器相当于一个linux系统(镜像运行后的实例称为容器),能执行cd、ls等命令,而且我们配置了jdk、maven、git,也就是说容器里的Jenkins可以帮我们拉取gitee的代码,通过maven的package命令打包成jar包,然后java -jar xxx运行。但是这样是在容器里面运行了,如果要使用Docker提供的MySQL、Redis等服务只能填IP,无法使用localhost,还有对外开放端口。所以要把jar布署到Docker里,而Docker命令只有宿主机才可以使用,所以容器需要用SSH连接到宿主机执行命令。

在Jenkins有相应的SSH插件,但我按步骤配置之后,就是连接不上。然后我发现了一个比较另类的方法,可能比较lowo(╥﹏╥)o。我直接手动把容器里的公匙放到宿主机了,然后在Shell脚本写ssh连接的使用就不用输入密码了。

本人菜鸟一枚,希望找到方法的大佬指导我一下~\(≧▽≦)/~!!!

大概的过程是,进入容器生成公匙,然后把公匙追加到宿主机的认证文件中,SSH信任就建立了,这样就实现免密登录了。

查看容器的ID

docker ps

进入容器

  • -i 交互操作
  • -t 终端
  • -u 指定身份进入

如果用docker attach进入容器,退出时容器也会停止运行,exec则不会。

docker exec -it -u root [容器ID] /bin/bash

生成公钥匙

出现提示输入信息则回车

 ssh-keygen -t rsa

把容器的公匙放到宿主机

scp /root/.ssh/id_rsa.pub root@宿主机的ip:/root/.ssh/authorized_keys

最后ssh 宿主机ip,如果不用输入密码直接连接则成功。

 

10.新建任务

配置了这么久终于进入正题了(⊙o⊙)

这里演示的是手动点击构建,并没有使用webhook触发执行此任务

 

构建触发器

这里一般测试环境我们希望,只要push代码到仓库,gitee就会触发webhook执行此任务(会给你配置的 url 发送一个post请求),这种比轮询要高效一点,但是生产环境的话建议还是使用手动点击构建。

 

构建环境

 

 

构建

重要 !!!重要 !!!重要!!!

这里的操作决定你的代码能不能打成jar包,能不能在宿主机的Docker跑起来。

 

添加两个!!!

 

添加把代码打包成jar的脚本,放在第一个Execute shell

需要修改两个地方,SERVER_NAME、JENKINS_NAME。

SERVER_NAME这里的值填你pom.xml里面name标签的值

JENKINS_NAME就是你上面创建任务时填写的名称

#!/bin/bash
# 上面这个东西不加,会报空间不足异常
# 注意:所有镜像,容器和应用的命名,最好不要有大写字母

# docker镜像/容器名字
SERVER_NAME=demo
JENKINS_NAME=first-demo
# 操作/项目路径(Dockerfile和Jar存放的路径)
BASE_PATH=/var/jenkins_home/docker/project/$SERVER_NAME
# 备份目录
BACKUP_PATH=/var/jenkins_home/docker/project/backup


# jar名字
JAR_NAME=$SERVER_NAME-0.0.1-SNAPSHOT.jar
# 源jar路径
SOURCE_PATH=/var/jenkins_home/workspace/$JENKINS_NAME/target/$JAR_NAME
# 当前日期时间
DATE=`date +%Y%m%d-%H%M%S`

# 备份
function backup(){
	if [ ! -d $BACKUP_PATH  ]; then
  		mkdir $BACKUP_PATH
	else
  		echo "备份文件夹已存在"
	fi

	if [ -f "$BASE_PATH/$JAR_NAME" ]; then
    	echo "$JAR_NAME 备份..."
        	cp $BASE_PATH/$JAR_NAME $BACKUP_PATH/$SERVER_NAME-$DATE.jar
        echo "备份 $JAR_NAME 完成"
    else
    	echo "$BASE_PATH/$JAR_NAME不存在,跳过备份"
    fi
}

# 迁移,构建好的Jar包,复制到DockerFile一起
function transfer(){

    echo "迁移代码开始"
    
    rm -rf $BASE_PATH
    
    mkdir -p $BASE_PATH
    
    echo "最新构建代码 $SOURCE_PATH 迁移至 $BASE_PATH ...."
        cp $SOURCE_PATH $BASE_PATH 
        
    echo "迁移完成"
    
}

# 生成Dockerfile文件
function dockerfile(){
	echo "开始生成Dockerfile文件"
    
echo """

FROM java:8

ADD $JAR_NAME $JAR_NAME

#更改容器时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 容器启动后执行的操作
CMD java -jar $JAR_NAME

""" > $BASE_PATH/Dockerfile
	echo "生成Dockerfile文件成功"

}


#入口
backup		# 1:备份
transfer	# 2:迁移
dockerfile	# 3:生成dockerfile

 

添加向宿主机布署的脚本,放在第二个Execute shell

需要修改APP_PORT、E_PORT、SERVER_NAME和最后三句命令的宿主机ip

APP_PORT是指springboot运行的端口,即application.properties/yml填写的server.port

E_PORT浏览器访问的端口,自定义

 

下面这段脚本的意思是,把容器和镜像的删除、镜像的制作、镜像的运行全都输出到一个叫/home/run.sh的脚本里,然后通过scp把脚本发送到宿主机,最后在宿主机执行命令。

#!/bin/bash
# 上面这个东西不加,会报空间不足异常
# 注意:所有镜像,容器和应用的命名,最好不要有大写字母

rm /home/run.sh

echo '#!/bin/bash

# docker镜像/容器名字
SERVER_NAME=demo
# 操作/项目路径(Dockerfile和Jar存放的路径)
BASE_PATH=/data/jenkins_home/docker/project/$SERVER_NAME

# 端口号
APP_PORT=8080 #应用的端口
E_PORT=8092 #服务暴露给外部调用的端口
# 容器id
CID=$(docker ps -aqf "name=$SERVER_NAME")
# 镜像id
IID=$(docker images -aqf reference="$SERVER_NAME")

function dockerBuild(){
	if [ -n "$CID" ]; then
		echo "存在$SERVER_NAME容器,CID=$CID,删除容器 ..."
			docker rm -f $CID 
		echo "$SERVER_NAME容器删除完成..."
	else
		echo "不存在$SERVER_NAME容器..."
	fi


	if [ -n "$IID" ]; then
		echo "存在$SERVER_NAME镜像,IID=$IID"
        docker rmi -f $IID
        echo "镜像删除完成"
		cd $BASE_PATH
		docker build -t $SERVER_NAME .
        echo "镜像构建完成"
	else
		echo "不存在$SERVER_NAME镜像,开始构建镜像"
		cd $BASE_PATH
        docker build -t $SERVER_NAME .
        echo "镜像构建完成"
	fi
    
    echo "启动容器..."
    docker run --name $SERVER_NAME -d -p $E_PORT:$APP_PORT $SERVER_NAME
    echo "容器启动完成"
}

dockerBuild	# 4:停止->删除旧容器,删除旧镜像,重建镜像,run容器 ' >> /home/run.sh

chmod +x /home/run.sh
ssh root@宿主机ip 'rm /home/run.sh' 
scp /home/run.sh root@宿主机ip:/home/
ssh root@宿主机ip 'bash /home/run.sh'

 

10.验证

 

参考博客:https://blog.csdn.net/z1353095373/article/details/107212714

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值