最近在整毕设,发现上线后每一次的修改应用到线上环境的时候就非常的烦躁,因为它总是重复着机械性的操作:打包->压缩->上传->解压->更新缓存。这种事情往复的操作显得十分没有意义,本着探索的精神,又发现很久没有水博客了,特此记录一下,水一水。
Jenkins
最早我在使用Jenkins的时候还是学校里面的一个校内项目,因为带着几个学弟学妹一起协同操作,索性我就用Github Actions+Jenkins实现了一套CI/CD,用下来也还不错。
但是,当时并没有深入学习Jenkins(其实现在也没有),想着速战速决,直接使用了最简单的命令执行,即直接远程执行Shell实现自动化部署。因为项目没有多分支,所以也久不需要CI的过程。
远程执行Shell并没有那么的优雅,因为包括clone、build都在服务器端运行,这是作为一个处女座所不能忍受的。
所以在这一次使用了更为广泛应用的Pipeline,其可定制化程度也更高,采用Docker作为编译环境,灵活性也更好。
基于Node.js持续部署
在Pipeline中,使用Docker作为编译环境,直接使用NodeJS官方镜像:
agent {
docker {
image 'node:16.13.2'
}
}
项目打包
在agent中定义好了打包环境后,在stages中定义对应的每一个步骤。
使用sh执行对应的Shell命令,由于有一定的版本冲突,本项目采用Yarn包管理进行依赖安装。令人惊喜的是NodeJS镜像内置了Yarn包管理。
由于官方源下载太慢,因此在每一次依赖安装前还需要修改到国内源,加快安装速度。
在打包完成后,使用zip命令将产物进行压缩,由于umiJS产物最终打包在dist目录下,故直接指定对应的dir即可。
stage('yarn env') {
steps {
sh '''node -v
yarn -v'''
}
}
stage('yarn install') {
steps {
sh 'yarn config set registry https://registry.npm.taobao.org'
sh 'yarn install'
}
}
stage('build') {
steps {
sh 'yarn run build'
}
}
stage('package') {
steps {
script {
zip archive: true, dir: 'dist/', glob: '', zipFile: 'deploy.zip'
}
}
}
部署
在一切准备就绪后,来到了部署环节。
部署即使用SSH远程执行命令,并使用SCP进行文件上传。这里使用的是SSH Agent插件,直接定义好全局凭证ID即可自动登入SSH(使用的是私钥免密登入)。
对于本前端项目部署而言,并无复杂的环境配置,仅为一些静态文件,直接上传到Web服务器对应的文件目录即可。
但是,由于每次打包后的文件并不一定文件名相同,直接替换文件可能导致后续服务器存储空间浪费,因此,还需要在每次解压部署前删除掉旧的版本。
这里踩了很久的坑,因为Nginx的配置文件.user.ini
在Web的根目录下无法删除,因此在删除的时候需要排除掉这个文件,否则会因为删除失败导致部署出错。但是,由于莫名其妙的字符问题,使用rm -rf !(.user.ini)
时无法正确执行,因此,需要采用xargs
进行删除。
对于服务器的相关IP、部署目录,已提前定义在environment
中。
stage('deploy') {
steps {
sshagent(credentials: ['credentials-id']) {
// 这里是将密钥加入到known_hosts, 同时配置对应的权限
sh '''
[ -d ~/.ssh ] || mkdir ~/.ssh && chmod 0700 ~/.ssh
ssh-keyscan -t rsa,dsa $SERVER >> ~/.ssh/known_hosts
'''
// send zip
sh "scp deploy.zip root@$SERVER:$SERVER_DIR"
// check dir is exist
sh '''ssh root@$SERVER "[ -d "$SERVER_DIR$SERVER_DIR_NAME" ] || mkdir $SERVER_DIR$SERVER_DIR_NAME"'''
// 开启通配符
sh '''ssh root@$SERVER "shopt -s extglob"'''
// remove old version
sh '''
ssh root@$SERVER \"cd $SERVER_DIR$SERVER_DIR_NAME && ls | grep -v .user.ini | xargs rm -rf\"
'''
// unzip
sh '''
ssh root@$SERVER "cd $SERVER_DIR && unzip deploy.zip -d $SERVER_DIR_NAME"
'''
sh '''
ssh root@$SERVER "cd $SERVER_DIR$SERVER_DIR_NAME chown -R www"
'''
sh '''
ssh root@$SERVER "cd $SERVER_DIR && rm deploy.zip"
'''
}
}
}
One comment
学到了!学到了!