前言
CI/CD是持续化继承和持续化部署的简称。目的是在开发的过程中,尽可能的降低人工成本,来完成部署操作。通过Jenkins自动流水线工作可以省去很多时间,对于程序开发者而言,将部署jar包、修改环境、日志记录等一系列操作集成到Jenkins任务内,省时又省力,本次将以Jenkins为核心进行从0到1的搭建与使用,并提供了Java单体项目与微服务的通用shell脚本供于使用。
环境说明
本文通过两种方式进行演示,第一种是基于Docker完成Jenkins的安装与应用,Docker使用版本为25.0.3;第二种是直接在本机上安装Jenkins(本人主机为Mac,所以使用Mac来安装,Linux基本也是一样的)
基于Docker的Jenkins更多适合训练,因为所有的操作都在容器内、方便后续转移以及迁移。但缺点是Jenkins与宿主机的环境不互通,如在容器打完的jar包只能放在挂载的目录里。而且Java项目需要连接的中间件也非常多、且因为jar包是跑在Jenkins容器内的,所以配置容器间通信又是一个复杂点。(推荐初上手的同学使用,先用docker搭建一个完成的任务进行测试)
而直接部署在本机上更适合生产环境,更加的灵活方便,shell脚本的操作空间更大,并且可以直接访问各种中间件,省去了容器间通信的配置调试时间
安装Jenkins(Docker)
基于Docker安装Jenkins大致分为拉取镜像与脚本编辑
拉取镜像
这里拉取镜像的时候我推荐直接去官网指定版本下载,我一开始通过后缀跟latest下载最新版导致很多插件都下不下来。最后去官网指定了一个版本才行 Jenkins-Docker镜像官网
# 修改前
docker pull jenkins/jenkins:latest
# 修改后(因为我本地开发环境用的是17,所以直接下载了一个内置17的jenkins,当然也可以不指定,后通过jenkins内部下载对应的Java版本,不过还是更推荐前者,而且在内部下载Java也比较麻烦。本文以前者进行!!)
docker pull jenkins/jenkins:2.448-jdk17
编写安装脚本
vim startJenkins.sh
这里简单介绍一下每个参数,其中**-u**需要特别注意!
-d:后台运行
-p:将容器的8080端口映射到宿主机的8081端口上
-u:使用 UID 为 0 的用户身份运行 Jenkins 容器(这里如果不指定-u 后面如果想要通过jenkins操作SHELL脚本会导致没有权限,所以需要使用root的身份运行容器)
一般情况下0为管理员角色,也可以使用id 0来检测是否是root用户
-v:挂载目录,将jenkins的工作目录挂在到宿主机内,这样使用jenkins操作目录时,我们本地也会有相同的反馈
–restart:在容器退出时自动重启容器
–name:配置容器名字
docker run -d \
-p 8081:8080 \
-u 0 \
-v /Users/sora33/docker/jenkins/data:/var/jenkins_home \
--restart=always \
--name jenkins \
jenkins/jenkins:2.448-jdk17
创建完成后,使用chmod -R赋值脚本权限并执行
# 赋值权限
chmod -R 755 startJenkins.sh
# 执行脚本
./startJenkins.sh
输入IP:8081
进入Jenkins主页面,首次进入页面会要求我们输入密码
密码会在容器内部打印出来
# docker logs 容器名
docker logs jenkins
将密码复制并进入下一级页面
安装Jenkins(非Docker)
Mac平台:
使用homebrew安装Jenkins,如未安装homebrew请先安装homebrew!!!
# 安装jenkins
brew install jenkins
# 注意,mac端安装完成后最后去/opt/homebrew/Cellar/jenkins/2.448/bin目录下看一下jenkins的环境变量是否正确!这里注意替换版本号!该目录下有jenkins
sudo vim jenkins
如果JAVA_HOME不是如图完整的路径而是@@HOMEBREW……
什么的请使用下面命令重新安装
brew reinstall jenkins
之后去/opt/homebrew/Cellar/jenkins/2.448
目录下修改局域网连接与端口号,默认只允许本机连接,改为0.0.0.0
所有人可连接,下面端口号默认是8080,这里我改为了8081
修改完成后,我们需要重启Jenkins
brew services restart jenkins
Linux平台:
Linux平台本人暂时未实践,不过只要成功安装Jenkins就没问题,区别在于文件的存放路径位置的不同,配置本质是一样的
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins
这里放出Linux下的Jenkins默认目录
/usr/lib/jenkins/:jenkins安装目录
/etc/sysconfig/jenkins:Jenkins配置文件目录
/var/lib/jenkins/:工作目录
/var/log/jenkins/jenkins.log:日志等
Jenkins配置
输入127.0.0.1:8081
进入Jenkins主页面,按照提示去对应目录拿到密码,下面我们需要安装常用的插件
安装插件
进入到该页面后,我们选择安装推荐的插件
PS:这里每个人的网络环境都不同,所以有可能导致一些插件无法正确下载下来
可以尝试改为清华大学的下载站,具体方法是进入刚刚我们挂载的工作目录内,也就是刚刚启动脚本-v所指定的目录,找到 hudson.model.UpdateCenter.xml文件。将里面的url改为https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
非Docker端可以先不配置镜像,一会直接通过页面配置
创建用户
这个账号相当于管理员账户,创建完成后后面URL一般也不需要改动
下面是配置Java与Maven,我们需要用到tools和plugins这两个模块
配置Maven
首先点击plugins
,继续点击Available plugins
,输入maven
,下载Maven Integration
,安装完成后我们
接着我们回到管理页面点击tools
Docker版配置
如果是Docker安装的话,我们直接在Jenkins容器内新装一个maven。翻到最底下找到Maven,新增Maven,输入Maven的名字和版本,选择版本最好跟本地一致,然后点击保存
Linux与Mac配置
一般mac与linux本机都已经安装完成maven了,如果没有安装请自行安装;安装完成后配置一下别名和路径即可
之后翻到最顶上,配置一下使用的maven配置文件,路径为setting.xml的地址,这样就可以使用本地的仓库
配置Java
Docker版配置
在同一个页面找到JDK安装部分,因为我下载的jenkins内置jdk17,所以直接进入jenkins容器内查看Java所在的目录
进入容器可以使用:docker exec -it c7c(容器id前3位) bash
配置别名,将路径输入,取消自动安装安装,点击保存
Linux与Mac配置
在同一个页面找到JDK安装部分,与maven一样,我们本机大概率是已经安装好Java的,同样只需配置一下别名和路径
页面上配置Jenkins下载源
除了通过该文件,我们也可以在插件管理中直接配置
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
Jenkins使用
Maven项目自动化构建
-
在主页面点击新建任务,选择构建一个maven项目,输入任务名称
-
下面我们输入这个任务的描述、最好选择丢弃旧的构建,在下面选择对应的策略,这里我选择的是只保留最近的3次构建,方便发生意外后直接回滚
-
下面我们来配置项目的Git地址,首先需要添加一个Git用户
以GitHub举例,像这样添加一个用户,用户名和密码就是你登陆GitHub的账号和密码
继续输入我们的Git地址以及所需要构建的分支
-
下面是构建的参数,这里的意思为执行clean package,清除再打包,跳过test阶段
-
最后需要配置构建完成后的操作,一般是通过执行shell脚本,将刚刚构建完成的项目跑起来并记录日志
- 脚本完成后我们点击保存并进行手动构建,尝试执行一次
boot项目通用shell脚本
boot脚本需要配置如下5个地方,通过序号对应
1:LOG_DIR与LOG_FILE,前者为日志所需要存储的路径,后者为日志文件名
3:将buildSoraProject改为jenkins的任务名称,这里我的任务名称即为buildSoraProject
4:配置jar包的名字,如果不知道jar包的名字,可以通过进入容器内该路径查看,或者直接在pom文件的build标签内提前指定好
6:配置buildId,只要唯一即可,一般为任务名称
7:目前只配置了字符集与时间,可以根据需求自己追加,例如常用的-Dspring.profiles.active=test
shell脚本:
#!/bin/bash
# 1.定义日志目录和日志文件的路径
LOG_DIR="$JENKINS_HOME/projectLog/buildSoraProject"
LOG_FILE="$LOG_DIR/sora_project_log.log"
# 2.确保日志目录存在,如果不存在则创建
mkdir -p $LOG_DIR
# 3.进入 Jenkins 的 workspace 目录下的 buildSoraProject/target 文件夹
cd $JENKINS_HOME/workspace/buildSoraProject/target
# 4.配置 jar包名称 sora33-0.0.1-SNAPSHOT.jar
JAR_FILE=sora33-project.jar
# 5.尝试停止已运行的 JAR 文件进程
PID=$(ps -ef | grep $JAR_FILE | awk '{print $2}')
if [ ! -z "$PID" ]; then
echo "Stopping existing Java process: $PID"
kill -9 $PID
fi
# 6.分配打包id
BUILD_ID=buildSoraProject
# 7.执行 jar 包 将日志输出到之前定义的日志文件中 如果时间异常再追加GMT+8,第一次可以先注释
nohup java -Dfile.encoding=UTF-8 \
-Duser.timezone=GMT+08 \
-jar $JAR_FILE > $LOG_FILE 2>&1 &
echo "Application is running, and logs are being written to $LOG_FILE"
cloud项目通用shell脚本
cloud脚本需要配置如下4个地方,通过序号对应
1:LOG_DIR_BASE 配置日志的路径,这里我放在Jenkins的工作目录下的
projectLog
文件夹里2:打包id,这里请务必将打包id与任务名称对应上,因为Jenkins会把该任务的结果输出在任务名称下的文件夹里
3:服务列表定义,这里需要配置项目所有的启动类,如下图是我的项目结构,可以参考shell脚本的格式对应你自己的项目结构
![]()
6:配置Java模块的启动命令,目前只配置了字符集与时间,可以根据需求自己追加,例如常用的-Dspring.profiles.active=test
#!/bin/bash
# 1.定义日志目录的基本路径
LOG_DIR_BASE="$JENKINS_HOME/projectLog"
# 2. 打包id
BUILD_ID=sora
# 3.服务列表定义
SERVICES=("sora-gateway" "sora-auth" "sora-modules/sora-user/user-server" "sora-modules/sora-system/system-server" "sora-modules/sora-system/spider-server")
# 4.停止所有服务
for SERVICE in ${SERVICES[@]}; do
JAR_FILE=$(find $JENKINS_HOME/workspace/$BUILD_ID/$SERVICE/target -name "*.jar" -print -quit) # 假设每个服务目录下只有一个jar包
if [[ ! -z "$JAR_FILE" ]]; then
PID=$(ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}')
if [[ ! -z "$PID" ]]; then
echo "Stopping $SERVICE (PID: $PID)"
kill -9 $PID
fi
fi
done
# 5.启动所有服务
for SERVICE in ${SERVICES[@]}; do
JAR_FILE=$(find $JENKINS_HOME/workspace/$BUILD_ID/$SERVICE/target -name "*.jar" -print -quit) # 假设每个服务目录下只有一个jar包
if [[ ! -z "$JAR_FILE" ]]; then
# 为每个服务创建一个专门的日志目录
LOG_DIR="$LOG_DIR_BASE/$(basename $SERVICE)"
mkdir -p $LOG_DIR
LOG_FILE="$LOG_DIR/$(basename $SERVICE)_log.log"
# 6.Java启动命令行配置
nohup java -Dfile.encoding=UTF-8 -Duser.timezone=GMT+08 \
-jar $JAR_FILE > $LOG_FILE 2>&1 &
echo "$SERVICE is running, logs are being written to $LOG_FILE"
else
echo "Jar file for $SERVICE not found."
fi
done
配置Aliyun的maven镜像源(Docker版)
PS:非Docker安装如果没有配置aliyun仓库地址,把下面的仓库地址加入到maven的conf目录下的settings的mirrors标签内即可。
因为Docker的maven还没配置aliyun仓库地址,并且是第一次使用maven,会在jenkins_home下生成一个tools文件夹,我们可以到挂载的data文件夹下查看,这里我们需要在maven内加入aliyun的仓库地址,具体路径为你挂载的路径/tools/hudson.tasks.Maven_MavenInstallation/Maven-3.9.1/conf
修改settings.xml
文件夹,将aliyun的仓库地址配置到mirrors标签内
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
结果测试
Docker
以boot项目举例,打包完成后我们可以在挂载目录中看到项目的日志输出,那我们要如何访问到项目呢?

因为我们启动jenkins容器时只指定了Jenkins的端口并没有把Jenkins内部的项目端口暴露出来,所以我们需要删除Jenkins容器,再次创建,这次加上我们的项目端口,注意因为我们删除的只是容器,挂载的data文件夹并没有删除,所以Jenkins的数据缓存还会留在我们宿主机上,当我们再次安装Jenkins时,历史数据都还在,所以千万注意不要删除挂载的目录!!
# 删除容器
docker rm -rf 容器id/容器名
修改我们的安装脚本,这次多暴露一个项目的端口1234
docker run -d \
-p 8081:8080 \
-p 1234:1234 \
-u 0 \
-v /Users/sora33/docker/jenkins/data:/var/jenkins_home \
--restart=always \
--name jenkins \
jenkins/jenkins:2.448-jdk17
# 再次启动安装脚本
./startJenkins.sh
通过查看1234端口,可以发现是docker在占用
调用接口也可以正常返回

非Docker
如果我们直接在宿主机部署项目,那么我们直接访问接口就可以。
直接放个日志图,项目启动成功并且接口也成功访问到
结束语
Jenkins的初步用法到这里就结束了,当然Jenkins也还有非常多的用法,大家也可以摸索一下,如果在搭建过程中遇到问题也欢迎留言,如果觉得有用可以分享给他人~
更多知识请移步个人博客:33sora.com