前端之路: 如何用 jenkins 构建部署项目

Jenkins(Build great things at any scale)

what is Jenkins ?

Jenkins是开源 CI(Continuous Integration:持续集成)&CD(Continuous Delivery:持续交付) 软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 知足任何项目的须要,支持各类运行方式,可经过系统包, Docker 或者经过一个独立的 Java 程序。前端

原理: 看图(画图工具node

img

why use Jenkins ?

  • 持续集成和持续交付:做为一个可扩展的自动化服务器,Jenkins能够用做简单的CI服务器,或者变成任何项目的连续交付中心。
  • 简易安装:Jenkins是一个独立的基于Java的程序,能够当即运行,包含Windows,Mac OS X和其余类Unix操做系统。
  • 配置简单:Jenkins能够经过其网页界面轻松设置和配置,其中包括即时错误检查和内置帮助。
  • 插件:经过更新中心中的1000多个插件,Jenkins集成了持续集成和持续交付工具链中几乎全部的工具。
  • 扩展:Jenkins 能够经过其插件架构进行扩展,从而为 Jenkins 能够作的事提供几乎无限的可能性。
  • 分布式:Jenkins能够轻松地在多台机器上分配工做,帮助更快速地跨多个平台推进构建,测试和部署。

Install

环境:ubuntu、docker、gitgit

$ cat /etc/issue
Ubuntu 16.04.6 LTS \n \l
复制代码

基于docker,不熟悉的能够先看看个人上一篇前端之路:紧跟潮流,docker简单应用github

  • 拉去镜像docker

    • $ docker pull jenkinsci/blueocean
  • 根据拉取的Jenkins镜像启动一个容器shell

     $ docker run \
      -d \
      --name jenkins \
      -u root \
      -p 49001:8080 \
      -v /var/jenkins_home:/var/jenkins_home \
      -v /var/jenkins_ssh:/root/.ssh \
      -v /var/run/docker.sock:/var/run/docker.sock \
      jenkinsci/blueocean
    
    复制代码

    解释:ubuntu

    • -d:守护模式,在后台运行。
    • -p:端口映射,49001是服务器端口(可根据本身状况更改,别忘记安全组开放端口),8080是容器端口(jenkins程序默认端口)。
    • -v:挂载数据卷,/var/jenkins_home:/var/jenkins_home:将Jenkins目录挂载到宿主机;/var/jenkins_ssh:/root/.ssh:将Jenkins的ssh挂载到宿主机,备份用,防止重启后丢失找不到。
  • 查看容器运行状况:浏览器

     $ docker ps
      CONTAINER ID      IMAGE                COMMAND                  CREATED        STATUS           PORTS                                NAMES
      08a54d4a804a      jenkinsci/blueocean  "/sbin/tini -- /usr/…"   7 days ago     Up 7 days        50000/tcp, 0.0.0.0:49001->8080/tcp   jenkins
    复制代码

    附图:安全

    img

    以上说明已成功,若容器意外退出,去掉-d 参数执行,查看log来排错。bash

  • 如今开始设置Jenkins,在浏览器访问 你的服务器ip:49001,会出现如下界面:

    img

    • 想进入要先解锁,密码就在 /var/jenkins_home/secrets/initialAdminPassword 文件里,怎么查看呢?两种方案:

      1. 首先要进入刚刚启动的jenkins容器里面,执行 $ docker exec -it jenkins bash,而后 $ cat /var/jenkins_home/secrets/initialAdminPassword
      2. 因为运行容器时,已经将Jenkins目录挂载到了宿主机,因此能够不用进入容器,直接在宿主机执行 $ sudo cat /var/jenkins_home/secrets/initialAdminPassword
    • 将上一步的密码复制到浏览器,点击continue按钮进行下一步。 附图:

      img

    • 安装插件,选择推荐安装便可。

=================================================

上面是基本的安装,我用的是时候官方文档仍是英文的,目前支持中文,想了解更详细内容,请去官网,下面开始教你们新建一个 自由构建的任务(鉴于目前网上大都是多机教程,即项目和jenkins不在一台服务器上,又考虑到小伙伴们手中可能只有一台本身的机器,因此我下面要讲的是 单机运行项目和Jenkins

=================================================

  • 打开 ip:49001进入首页,点击系统管理:

    img

  • 首先点击插件管理,搜索并安装一下插件(若已安装列表已存在可忽略):

    • Build Name Setter
    • Dingding[钉钉] Plugin
    • Build Timestamp Plugin
    • Git Parameter Plug-In
    • Publish Over SSH
    • SSH Slaves plugin
    • Timestamper
  • 而后点击系统设置:

    • 找到 Build Timestamp (上面的插件提供的),进行以下设置:

      • Asia/Shanghai
      • yyyy-MM-dd-HH-mm-ss-SSS

      img

    • 找到 Publish over SSH,这个相对麻烦些,进行以下设置:

      img

      说明:

      • Passphrase:SSH的password。有两种状况:1. 使用username/password登陆时为username的password;2. 使用私钥登陆时为私钥的password。
      • Path to key:SSH私钥的文件路径。能够是绝对路径,也能够是相对$JENKINS_HOME的相对路径。
      • Key:私钥,私钥导出后的文本内容,假设“Key”和“Path to key”都设置,则“Key”的优先级较高,此时“Passphrase”中设置的内容应该是私钥的password。
      • Disable exec:禁止在目标机上运行命令,勾选后将会忽略在Job配置中“Exec command”选项中设置的命令。

      补充:因为Jenkins是在docker容器中运行的,因此上面的配置应该是容器的ssh配置,而不是宿主机的。如上图,我是经过ssh私钥进行的登录。

      步骤:

      • $ docker exec -it jenkins sh,进入容器。
      • $ ssh-keygen -m PEM -t rsa -b 4096,生成ssh私钥及公钥(默认在 ~/.ssh/root/.ssh 目录中),能够一路回车,若设密码的话,需在“Passphrase”中填写。
      • $ cat ~/.ssh/id_rsa,查看私钥,把私钥copy到上图的“key”设置中。
      • $ cat ~/.ssh/id_rsa.pub,查看公钥,把公钥copy到宿主机的 ~/.ssh/authorized_keys 中。

      至此,Jenkins的ssh配置就完成了,接下来要配置远程机(我们是单机,因此宿主机就当成远程机来配置)的SSH Servers了:

      img

      说明:

      • Name:SSH节点配置的名称,可随意设置,他将在job配置的“SSH Server”的下拉列表中,如图:
        img
      • Hostname:经过SSH链接到的机器的主机名或IP。
      • Username:SSH服务使用的username,使用key进行链接时为key指定的username。
      • Remote Derictory:运程机器上真实存在的文件夹,并且“Username”指定的用户要有訪问此文件夹的权限。插件将把文件传送到此文件夹下。通常是存放项目的目录。
  • 测试,点击“Test Configuration”按钮,如success,这配置成功,进行下一步,新建任务。

下面开始新建任务:

  • 在首页点击“新建任务”,输入名称(建议和github的项目名称保持一致),选择第一个“构建一个自由风格的软件项目”,而后点击肯定:

    img

  • 返回首页,能够列表中看到刚刚新建的任务,点击名称,进入任务详情:

    img

  • 在任务详情页,点击配置,进行项目配置:

    img
    配置:
    img
    img
    img
    img
    img
    补充:(shell脚本都在项目的deploy目录下)

    • Exec command:

      #!/usr/bin/env bash
      echo '************************************** 发送至服务器成功 **********************************************'
       # 项目名,取自环境变量
      projectName="${JOB_NAME}"
      dockerImageName=${projectName}-${BUILD_TIMESTAMP}
       # step1 解压源代码
      echo " ************************************* 解压源代码${dockerImageName}.tar.gz start *************************************"
      
      projectPath='/var/nodejs/' # 须要单独给用户赋目录/var/nodejs/的权限 sudo chown ubuntu /var/nodejs/
      sudo mkdir -p ${projectPath}${projectName} || true \
      && cd ${projectPath}${projectName} \
      && sudo rm -rf *  # 删除里面的数据
      
      sudo tar -zxf ../${dockerImageName}.tar.gz -C ./ \
      && sudo rm  ../${dockerImageName}.tar.gz   # 删除发布过来的包
      
      echo " ************************************* 解压源代码${dockerImageName}.tar.gz finish *************************************"
       # step2 构建docker镜像
      echo " ************************************* 构建docker镜像${dockerImageName} start *************************************"
      sudo docker build -t ${dockerImageName} --force-rm .
      echo ' ************************************* 构建docker镜像 finish *************************************'
       # step3 重启容器
      echo "************************************* 使用镜像${dockerImageName}启动容器${projectName}  start *************************************"
      # 错误日志统一存放在/var/nodejs/logs/${projectName}
      sudo mkdir -p /var/nodejs/logs/${projectName} || true \
      && sudo docker stop ${projectName} || true \
      && sudo docker rm ${projectName} || true \
      && sudo docker run -d --net=host --name ${projectName} -v /var/nodejs/logs/${projectName}:/var/nodejs/${projectName}/logs ${dockerImageName}
      
      echo "************************************* 使用镜像${dockerImageName}启动容器${projectName}  finish *************************************"
      
      echo '************************************************ 查看docker容器状况: ************************************************ '
      sudo docker ps -a
      echo '************************************************ 查看docker容器状况: ************************************************ '
      复制代码
    • 若是项目须要在容器里构建,一般初次构建时间相对较长,因此能够把高级设置中的“Exec timeout”设的稍微大一些。

    • 构建-执行shell-命令:

      #!/usr/bin/env sh
      projectName="${JOB_NAME}"
      dockerImageName=${projectName}-${BUILD_TIMESTAMP}
      
      echo '*********************************** 准备打包从Github仓库拉取的代码...*********************************************'
      echo "**********${WORKSPACE}**********"
      tar --exclude=node_modules --exclude=.git --exclude='*.tar.gz'  -vzcf /tmp/${dockerImageName}.tar.gz -C  ${WORKSPACE} .  \
      && mv /tmp/${dockerImageName}.tar.gz  ${WORKSPACE} \
      && echo '*********************************** 打包成功 *********************************************' \
      && echo '************************************** 准备发送至服务器... **********************************************'
      复制代码
    • 构建后操做,钉钉通知配置教程

  • 完成项目的任务配置,点击保存。

  • 返回任务详情也,点击“Build with Parameters”,选择分支,点击“开始构建”:

    img

  • 在构建历史列表中,点击最新的一条构建记录,再点“击控制台输出”,可查看构建的log:

    img
    最终log输出:Finished: SUCCESS,则成功。v 构建后,钉钉会收到通知。

若是有问题,须要版本回滚怎么办呢?

咱们能够新建一个任务用于版本回滚:

  • 回到首页,点击新建,起个名字如:newblog-rollback。

  • 在列表点击newblog-rollback,进入任务详情,点击配置,进入配置页:

    img
    img
    img
    补充:(shell脚本都在项目的deploy目录下)

    • Exec command:

      #!/usr/bin/env sh
      
      trim()
      {
          trimmed=$1
          trimmed=${trimmed%% }
          trimmed=${trimmed## }
          echo "$trimmed"
      }
       # projectName=$(trim "${container_name}")
      projectName="newblog"
      
      dockerImageName=$(trim "${image_name}")
      
      echo "******************************************* 回退到镜像${image_name} ,并启动容器${container_name} **************** *******************************"
      sudo mkdir -p /var/nodejs/logs/${projectName} || true \
      && sudo docker stop ${projectName} || true \
      && sudo docker rm ${projectName} || true \
      && sudo docker run -d --net=host --name ${projectName} -v /var/nodejs/logs/${projectName}:/var/nodejs/${projectName}/logs ${dockerImageName}
      echo "************************************* 使用镜像${dockerImageName}启动容器${projectName}  finish *************************************"
      复制代码
  • 测试版本回滚,首先,你要知道要回退到哪一个版本,在newblog任务列表中copy你要回退的镜像名:

    img
    img
    img
    img
    最终log输出:Finished: SUCCESS,则成功。

最终成果:http://140.143.0.171:8080

【参考】:

  1. jenkins.io/
  2. N-blog

===🧐🧐 文中不足,欢迎指正 🤪🤪===

===内容有点多,自我感受写的很差,但不知怎么优化,有好的建议欢迎提===

相关文章
相关标签/搜索