前言
上节讲了SpringBoot上的打包。但这些过程都是手动的,在实际的开发测试时,自动化的打包部署,可以大大提升团队开发的效率
一、去官网下载
1.1 官网安装命令
对于如何安装的问题,我向来推荐官网
wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install fontconfig
sudo apt-get install jenkins
1.2 错误解决
如果出现如下错误:
Created symlink /etc/systemd/system/multi-user.target.wants/jenkins.service → /lib/systemd/system/jenkins.service.
Could not execute systemctl: at /usr/bin/deb-systemd-invoke line 148.
则键入:
journalctl -u jenkins
journalctl -xeu jenkins.service
查看到底错哪了,显示说:
jenkins: failed to find a valid Java installation
jenkins.service: Main process exited, code=exited, status=1/FAILU>
jenkins.service: Failed with result 'exit-code'.
Failed to start Jenkins Continuous Integration Server.
这说明jenkins没找到jre环境
用vim打开/lib/systemd/system/jenkins.service
我们可以看到,执行的脚本是/usr/bin/jenkins,用vim打开它
其实,应该是jenkins无法获取我在root中设置的环境,那就把jenkins改成root。
再次vim /lib/systemd/system/jenkins.service,更改如下配置
[Service]
...
#执行脚本前,运行一下设置环境变量
#这样做的好处是,即使在jenkins的pipline中,也可以使用linux的环境变量了
ExecStart=/bin/bash -c 'source /etc/profile && /usr/bin/jenkins'
Environment="JENKINS_PORT=8888"
#让jenkin放到nginx后面
Environment="JENKINS_PREFIX=/jenkins"
User=root
Group=root
systemctl daemon-reload
systemctl start jenkins
1.3 配置nginx
location /jenkins {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
}
这样一来,我们就可以通过192.160.0.64/jenkins访问jenkins了
二、jenkins插件安装与设置
2.1 初始化
进入jenkins,首先页面如图所示
vim /var/lib/jenkins/secrets/initialAdminPassword
把密钥拷贝过来,进入jenkins,然后安装需要的插件。
尤其要安装的是SSH Pipeline Steps,用于远程访问
2.2 记得安装git
如果出现Failed to connect to repository : Error performing git command: git ls-remote -h https://gitee.com/**/*.git HEAD 这一类的错误时,说明宿主机没有装git,apt install git一下即可
2.3 git的账户密码设置
点击Credentials
添加一个凭证
三、流水线自动编译部署
3.1 目标
上节我们讲了SpringBoot下的打包,把lib,resource,config等分离了出去。所以我们这次的自动化编译,需要可以勾选是否更新lib,resource,config的选项。
同一个项目,可能被部署为多个实例,不同实例部署在不同端口。
编译好的项目,将被部署到/WORK/APP/study2024-class004/$appName,并调用startup.sh脚本启动项目
3.2 参数化
勾选This project is parameterized,添加如下参数
参数名 | 默认值 | 描述 |
---|---|---|
profile | test | 环境 |
appName | app001 | 部署文件夹 |
port | 8081 | 端口 |
version | 1.0.0 | 版本 |
isUpdateCode | true | 是否更新代码 |
isUpdateBin | false | 是否更新bin |
isUpdateConfig | false | 是否更新配置文件 |
isUpdateLib | false | 是否更新lib包 |
isUpdateStatic | false | 是否更新静态资源 |
isUpdateMapper | false | 是否更新mapper |
gitTag | master | git分支 |
要值得注意的是,gitTag是Git parameter,Advance里,Branch Filter设置为origin/(.*)
3.3 jenkins文件
import java.text.SimpleDateFormat
node{
def remote = [:]
remote.name = '地下室主机'
remote.host = '192.168.0.64'
remote.user = 'root'
remote.password = '???@1314'
remote.deploymentHome = "/WORK/APP/study2024-class003"
remote.allowAnyHosts = true
def app = [:]
app.module = "busy/general-test"
app.name = "nbr"
app.version = "${version}"
app.cd = "${appName}"
app.port = "${port}"
def timestamp = currentBuild.getTimeInMillis()
def formattedTimestamp = new SimpleDateFormat("yyyy-MM-dd-HH_mm_ss").format(timestamp)
stage("拉取代码"){
git branch: "${gitTag}", credentialsId: 'gitSec', url: 'https://gitee.com/hataksumo/study2024-class004.git'
}
stage("编译代码"){
sh """
cd code
mvn clean
mvn package -pl busy/general-test -am -P${profile} -Dmaven.test.skip=true
"""
}
stage("远程推送"){
echo "停服"
sshCommand remote: remote, failOnError:false, command: """
cd ${remote.deploymentHome}/${app.cd}/bin
./shutdown.sh --appName ${app.cd}
"""
if(isUpdateCode == "true"){
echo "备份jar包"
sshCommand remote: remote, failOnError:false, command: "mv ${remote.deploymentHome}/${app.cd}/${app.name}-${app.version}.jar ${remote.deploymentHome}/${app.cd}/${app.name}-${app.version}.jar.bac"
echo "拷贝jar包"
sshPut remote: remote, from: "code/${app.module}/target/${app.name}.jar", into: "${remote.deploymentHome}/${app.cd}/${app.name}-${app.version}.jar"
echo "删除jar包"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/${app.name}-${app.version}.jar.bac"
}
if(isUpdateConfig == "true"){
echo "删除config"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/config"
echo "拷贝lib包"
sshPut remote: remote, from: "code/${app.module}/target/config", into: "${remote.deploymentHome}/${app.cd}"
}
if(isUpdateLib == "true"){
echo "删除lib包"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/lib"
echo "拷贝lib包"
sshPut remote: remote, from: "code/${app.module}/target/lib", into: "${remote.deploymentHome}/${app.cd}"
}
sshCommand remote: remote, failOnError:false, command: "mkdir ${remote.deploymentHome}/${app.cd}/resources"
if(isUpdateStatic == "true"){
echo "清除resources/static文件"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/resources/static"
echo "拷贝static文件"
sshPut remote: remote, from: "code/${app.module}/target/resources/static", into: "${remote.deploymentHome}/${app.cd}/resources"
}
if(isUpdateMapper == "true"){
echo "清除resources/mybatis文件"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/resources/mybatis"
echo "拷贝mybatis文件"
sshPut remote: remote, from: "code/${app.module}/target/resources/mybatis", into: "${remote.deploymentHome}/${app.cd}/resources"
}
if(isUpdateBin == "true"){
echo "清除bin文件"
sshRemove remote: remote, failOnError:false, path: "${remote.deploymentHome}/${app.cd}/bin"
echo "拷贝bin文件"
sshPut remote: remote, from: "code/${app.module}/target/bin", into: "${remote.deploymentHome}/${app.cd}"
echo "赋予可执行权限"
sshCommand remote: remote, failOnError:false, command: """
cd ${remote.deploymentHome}/${app.cd}/bin
chmod +x startup.sh
chmod +x shutdown.sh
"""
}
echo "启服"
sshCommand remote: remote, command: """
source /etc/profile
echo "path = $PATH"
cd ${remote.deploymentHome}/${app.cd}/bin
./startup.sh --version ${app.version} --appName ${app.cd} --port ${app.port}
"""
}
}
3.4 启动
点击后,就可以自动的编译部署了。