Jenkins部署前端服务
一、Jenkins简介
官方说明:
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。
官网地址:
总之:
使用Jenkins,可以实现一键部署发布。
Jenkins从SVN拉取代码 > 部署至发布项目的服务器 > 并启动服务。代替人工运行buil命令打包 > 上传至服务器 > 重启服务。
二、安装Jenkins
后端已在服务器上安装了Jenkins,详细安装过程不赘述,实话是我也不会。
三、安装插件(nodejs)
- 因需要ssh上传包至服务器,需要publish over ssh插件。
- 因前端使用node.js打包,需要nodejs插件。
- 前者,后台已安装,在此不赘述,主要讲解nodejs插件安装过程。
1、安装nodejs
依次点击Manage Jenkins > Manage Plugins
在可选插件tab,搜索nodejs,选中后点击安装按钮。
此处已安装,所以无法搜索到。
安装完成后,可在已安装搜索到。
2、配置nodejs
依次点击Manage Jenkins > Global Tool Configuration
往下翻,找到nodejs。
点击nodejs安装按钮。
填写别名,用于后续配置打包时候选择,选中相应使用的nodejs版本号,点击应用按钮。
四、配置服务器
配置项目发布需使用的服务器。
依次点击Manage Jenkins > Configure System。
往下翻到SSH Servers,已添加的服务器就无需再添加了,后续配置直接选用即可,若此处未添加的可添加一个服务器。
点击新增按钮。
服务器命名,用于后续配置选择,输入服务器IP和登录服务器的用户,点击高级,输入服务器的用户密码。
输入密码后,点击测试按钮,可测试服务器的连通性,校验配置是否正确。
连接成功后点击应用按钮即可。
五、配置项目
在tab页选中html,点击左侧新建Item。
输入任务名称,建议命名:服务器IP-服务说明。
选择第一个Freestyle project,点击OK。
依次进行项目的配置:
- General:通用信息,不重要,可不配置。
- 源码管理:因我们项目使用SVN进行代码的版本管理,所以选择Subversion,配置该项目的SVN地址,添加一个连接SVN的用户。Jenkins将使用该用户去该SVN地址拉取代码。
- 构建环境:勾选Provide Node & npm bin/ folder to PATH,选择之前配置的nodejs。
构建:
1、点击增加构建步骤,选择Execute shell。
也就是Jenkins从SVN拉下代码后,需要执行什么命令进行打包和压缩。
输入脚本:
bash
复制代码
npm install # 因为node_modules没有提交所以需要install
npm run build # npm命令打包项目
find ./dist -type d -name ".svn"|xargs rm -rf # 删除dist包下所有的.svn文件
rm -rf dist.tar.gz # 删除上一个\已存在的dist压缩包
tar -zcvf dist.tar.gz dist # 将新打的dist包进行压缩
2、再次点击增加构建步骤,选择Send files or execute commands over SSH。
选择已配置的、要发布的服务器。
Source files输入需要上传的包名字。
Remote directory输入要上传至服务器的哪个位置。
Exec command输入上传完成后需要执行的脚本,包括备份、启动等。
输入脚本:
bash
复制代码
cd /usr/local/nginx/html # 确保进入对应包目录
mv dist dist.`(date +%Y%m%d_%H:%M)` # 备份上一个\已存在的dist.当前日期_时间
tar -zxvf dist.tar.gz # 解压dist压缩包
rm -rf dist.tar.gz # 解压完成后删除tar包
cd ../sbin
./nginx -s stop # 强制停止nginx
./nginx # 启动nginx
点击应用,项目创建完成。
六、一键部署项目
点击左上角Dashboard,回到主界面。
点击html页签,选则要发布的项目,点击运行按钮即可。
左下角的构建执行状态会有正在发布的项目,点进去可以查看执行情况,部署失败根据日志定位问题。
完成以上的配置后,只需点击项目的运行按钮,Jenkins就拉下最新的代码进行部署,后续还可以进行自动定时部署等配置,有兴趣的自行摸索。
注意:需要提交代码到SVN,因为Jenkins拉的是SVN上的代码,如果自己本地暂时不想提交,那你自己手动部署吧。
七、附创建pipeline类型的项目
原来(五、配置项目)是创建Freestyle project类型的项目,接下来是讲解如何创建Pipeline类型项目。
先看一下Pipeline项目的差别,建好以后长得不一样,每次构件,每个步骤列得比较清楚,至于如何创建步骤如下。
1、在对应tab页签下,点击左侧新建Item。
2、输入任务名称,建议命名:服务器IP-服务说明。
选择第三个Pipeline,点击OK。
3、输入描述即可
This project is parameterized,可以不勾选,该处勾选并选择了布尔类型的参数,随便输入了一个“防止多次启动”的参数名称,目的是因为,创建好以后点击启动按钮页面不跳转,容易重复点击,添加了该参数页面会跳转,需要二次点击开始构建才正式启动项目。参数无实际意义,只是为了防止多次点击启动。
4、输入脚本即可
附脚本和说明:(对应项目各自进行修改,感谢林老板提供的脚本模板)
php
复制代码
pipeline {
agent any
environment {
REPOSITORY = "" // SVN仓库地址
SVN_ID = "" // SVN用户凭证(Manage Jenkins > Manage Credentials可查看)
t_ssh = "" // 远程部署服务器 需要在该服务器设置Jenkins免密登录 具体详见下面的说明
t_dir = "" // 远程部署文件夹目录
micro_name = "" // docker里配置的该服务的名称 定义变量在这个前面便于不同的项目进行修改
}
stages {
stage('获取代码') {
steps {
echo "start fetch code from ${REPOSITORY}"
// deleteDir()
checkout([$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[
cancelProcessOnExternalsFail: true,
credentialsId: SVN_ID,
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: REPOSITORY
]],
quietOperation: true,
workspaceUpdater: [$class: 'UpdateUpdater']])
}
}
stage('构建代码') {
steps {
echo "start package"
// 打包脚本 视情况修改
sh """
cd ${ WORKSPACE }
sed - i 's/\("microServe": "\).*/\IP"/g' public / static / microConfig.json
npm install
sleep 1s
npm run build
find ./dist -type d -name ".svn"|xargs rm -rf
rm - f dist.tar.gz
tar - zcvf dist.tar.gz dist
"""
}
}
stage('复制文件') {
steps {
// 上传包脚本 视情况修改
sh """
echo "start copy file"
scp dist.tar.gz ${ t_ssh }: ${ t_dir }
ssh ${ t_ssh } "
cd ${ t_dir };
mv ${ t_dir } /dist ${t_dir}/dist.`(date +%Y%m%d_%H:%M)`;
tar - zxvf dist.tar.gz;
rm - rf dist.tar.gz
"
"""
}
}
stage('部署') {
steps {
// 启动包脚本 视情况修改
sh """
echo "start deploy"
ssh ${ t_ssh } 'docker restart ${micro_name}'
"""
}
}
}
post {
always {
echo '构建结束...'
}
success {
echo '恭喜您,构建成功!!!'
}
failure {
echo '很抱歉,构建失败!!!'
}
unstable {
echo '该任务已经被标记为不稳定任务....'
}
changed {
echo ''
}
}
}
其他说明:
a、// deleteDir()
删除Jenkins拉包所在文件夹的所有文件,经过测试,没有必要删除,Jenkins是从SVN上update文件,已删除的会被删除,且npm打包的时候也会删除dist文件夹。
注释删除所有文件的好处在于,不会删除node_moudules里面的包,这样npm install的时候速度快很多。
b、npm install
如果涉及私库的包,只需在后面跟上私库地址即可。
比如:npm install --registry http://IP:4873
c、sed -i 命令是微前端的主应用里需要写明子应用的服务地址,然而不同的项目服务地址不同,所以采用该方法动态写入。
正则表达式在文件中匹配并替换microServe的IP地址,需要注意的是,该步骤需要在npm run build打包以前执行。
swift
复制代码
sed -i 's/\("microServe": "\).*/\IP"/g' public/static/microConfig.json
d、Jenkins自动打包的dist大小是本地手动npm run build的两倍
经过查看发现,本地从svn拉的代码,只有最外层有一个.svn文件,且npm run build打包以后dist中无.svn文件。
而查看Jenkins的工作空间,从svn拉的代码,很多地方都有.svn文件,且通过命令行自动打包以后dist中很多地方都有.svn文件。
因此导致,Jenkins自动打包的dist大小是本地手动npm run build的两倍。
解决思路如下:
- ①配置Jenkins从svn拉代码时忽略掉.svn文件
- ②配置npm打包时忽略掉.svn文件
- ③打包完成后通过命令行删除dist下所有.svn文件
因为前两种方式尝试无果,最终使用最后一种方法,只需要添加如下命令即可:
bash
复制代码
find ./dist -type d -name ".svn"|xargs rm -rf
e、服务器之间免密登录
在 安装Jenkins的服务器上 给 需要远程部署的服务器 配置免密登录。
命令如下:
css
复制代码
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.10.17.141 -p 22088
root是目标服务器(需远程部署服务的服务器)的用户名
10.10.17.141是目标服务器的IP
执行输入密码即可
测试是否成功,执行命令
ssh 10.10.17.141(目标服务器的IP)看是否还需要输入用户密码
-p 22088 追加端口号 若无-p命令 默认端口号为22
f、ssh远程服务器不使用默认端口号22
ssh远程服务器默认端口号为22,若服务器对外开放的远程端口非22,比如22088,则在进行远程操作时需要追加端口号。
比如:
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.10.17.141 -p 22088scp -P 22088 dist.tar.gz ${t_ssh}:${t_dir}ssh -p 22088 ${t_ssh} "ssh -p 22088 ${t_ssh} 'docker restart ${micro_name}'
注意:
- scp后面跟的大写P,ssh后面跟的小写p!!!
g、启动包脚本 权限和捕获异常的问题
python
复制代码
stage('构建代码') {
steps {
echo "start package"
// 打包脚本 视情况修改
sh """
cd ${WORKSPACE}
sleep 1s
chmod -R 777 node_modules/.bin
"""
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh """
npm run build
"""
}
sh """
find ./dist -type d -name ".svn"|xargs rm -rf
rm -f dist.tar.gz
tar -zcvf dist.tar.gz dist
"""
}
}
- 1、无需install的去掉npm install命令。
- 2、.bin下文件执行报错没有权限,加上chmod命令。
- 3、catchError捕获异常,防止npm run build时报错Jenkins不再继续后续操作。
h、获取不到最新版本的代码
明明提交了最新的代码至svn,但使用Jenkins部署的时候一直没有获取到最新的代码,因为svn服务器时间不一致。
解决办法:
在Jenkins的svn配置后面追加@HEAD即可。
REPOSITORY="SVN仓库地址@HEAD"
5、点击应用,完成创建。
回到第一步的tab页签,点击启动按钮,再点击“开始构建”按钮,即可完成项目的一键发布。
参考文档:
liubing.me/jenkins-vue… www.jianshu.com/p/93238a7ad…
其他问题:
1、Jenkins部署系统时候报错文件冲突
打开日志定位报错点,如图所示:
是不是有点眼熟,这不是和svn冲突长得一样嘛。
之前都正常,突然报错,提示是文件冲突。
于是打开Jenkins所部署的服务器,找到当前系统的工作空间。
发现因为提交代码修改了microConfig.json文件,Jenkins部署时也去修改这个文件导致版本冲突。
于是删掉冲突版本,再次点击部署即可。
2、pipeline类型的项目升级node版本
依次点击 Manage Jenkins > Configure System
在全局属性勾选 环境变量 Environment variables
修改键PATH的值/Data/cloud/env/node/node-v14.21.0-linux-x64/bin
对应的node版本路径,为当前Jenkins所在服务器,下载的对应版本的node安装路径。
如图所示:
附:linux服务器安装node
- a)、官网下载所需的node版本
https://nodejs.org/dist/v14.21.0/ - b)、解压安装包 若下载的是xxx.tar.xz文件,解压命令为
tar -xvf xxx.tar.xz - c)、修改环境变量 修改:/etc/profile文件
ini
复制代码
#SET PATH FOR NODEJS
export NODE_HOME=NODEJS解压安装的路径
export PATH=$NODE_HOME/bin:$PATH
- d)、环境变量需重启生效
source /etc/profile - e)、查看当前node版本
node -v