Jenkins部署前端服务

226 阅读10分钟

Jenkins部署前端服务

一、Jenkins简介

官方说明:

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。

官网地址:

www.jenkins.io/index.html

总之:

使用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 22088
  • scp -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部署系统时候报错文件冲突

打开日志定位报错点,如图所示:

image.png

是不是有点眼熟,这不是和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安装路径。

如图所示:

pipeline的node版本修改.png

image.png

附: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