jenkins+docker+github webhook+multibranch pipeline从0到1实现自动化构建

前言

在日常工作中,通过手动构建的情况比比皆是,尤其是在提测后 -> 上线前的这段时间,频繁的提交、推送、构建、部署,在多人合作的情况下我们不免因为手动的构建过程出现一些瑕疵影响到整体的测试进度从而导致上线时间的风险性,这个时候,自动化构建的优势就体现出来了

之前了解过一些 gitlab ci 相关的知识也做过一些尝试,发现特别方便,代码提交后就可以自己进行代码构建发布,但是有一点不好,每个项目都是独立的一个 ci 不能统一进行管理,只能在各自的管道当中去进行维护,这样对于多项目多分支的情况来说,其实并不够友好

正文

接下来就开始要从0到1实现一整套通过 jenkins 来完成自动化构建,下面的图片会很多因为我把所有的步骤全部截图了,之前吃过网上图片截图不全,在从未接触过 jenkins 的阶段很难学习,这次我就多截一些图,大家多花一点流量,但是可以保证每一个步骤都是完善的,学习成本低的

温馨提示:在看 jenkins 文档时建议不要只看中文文档,很多死链接,或者内容更新不全的地方对于学习 jenkins 会有很大的阻
碍如果发现某些文档内的东西跑不通了,建议查看英文版
复制代码

技术选型

jenkins docker

在自己调研和朋友之间互相沟通的情况下,最终还是选择了使用 jenkins 来进行自动化构建的实现,可以根据项目的钩子来进行项目自动化构建,一整套 jenkins 可以在本地调试,也可以发布到线上使用,支持多分支多项目的整体维护,由于出现的比较久,插件方面发展的也比较完善,所以最后选择了 jenkins

由于我们项目都是在容器里面进行部署的,所以为了可以完全的符合项目的使用,所以 jenkins 和项目的构建,我都是通过 docker 去进行安装的

multibranch pipeline

其实从构建层面来讲 jenkinspipeline 管道项目是最方便的,而且网上相关的资料基本都是单分支构建的,学习起来其实成本会低很多

但是实际情况来说,我们多分支的情况还是比较多的,通过 git flow 在进行敏捷开发的时候这种情况必不可少,所以为了能够完全的迎合业务,我选择了 multibranch pipeline,由于网上相关资料的不完善,和各种陈旧的知识,导致了学习发生了严重的阻碍性,还好最后还是坚持过来了

jenkins docker

首先我们要在自己的本地安装 docker 客户端

image.png

通过 docker -v 检查是否可以正常使用

image.png

发现 docker 正常安装的情况下,我们开始构建一个 jenkins 的镜像

docker run \
  --rm \
  --name jenkins_demo \
  -u root \
  -p 8080:8080 \
  -v jenkins-data:/var/jenkins_home \
  -v "$HOME":/home \
  -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/bin/docker\
  jenkinsci/blueocean
复制代码

在构建完成后,会出现一堆星号里面就是密码

image.png

上面的命令中,本地端口指向了 80,通过 localhost:8080 访问时,页面会显示

image.png

输入上方截图的密码,忘记密码后可通过 /var/jenkins_home/secrets/initialAdminPassword 找回密码

image.png

点击安装推荐的插件,剩下的在项目启动后在进行安装即可,安装完成后会自动跳转到如下页面

image.png

添加完成后,显示实例配置页面,这里直接保存并完成就好

image.png

jenkins 准备已就绪,点击 开始使用 jenkins

image.png

进入页面后,正常应该显示如下界面

image.png

配置 github 服务

现在我们要进入 Manage Jenkins -> Configure System 查找到 github 选项,添加一个 github 服务器

image.png

点击添加凭证,类型选择 Secret text

image.png

Secret 的值通过 github 个人的 settings -> Developer settings -> Personal access tokens 点击 Generate new token

image.png

选择如下选项,点击 Generate token

image.png

复制上方的 token 添加到 Secret,添加完成后,点击 连接测试 按钮

image.png

当显示出 Credentials verified for user nextdoorUncleLiu, rate limit: **** ,说明 jenkinsgithub 服务器连接成功了

点击 新建item,选择多分支流水线,输入任务名称 My Pipeline

image.png

跳转到如下页面

image.png

选择 github 源 添加 httpsgithub 地址,凭据内只能添加账户和密码,就是 github 的账号和密码,点击验证后,提示 Credentials ok. Connected to https://github.com/nextdoorUncleLiu/jenkins-test. 说明可以连接成功了

由于是从0到1的搭建,我们不做太复杂的配置,保证自动化构建的完全实现即可

点击保存按钮,仓库开始扫描

image.png

正常完成就是这种状态

配置 webhook

webhook 最主要是通过 githubpushforks 等阶段发送钩子到 jenkins 服务器,通知 jenkins 服务器进行自动化操作

首先,我们不可能在每次的调试当中,都发送到测试服务器上测试项目,所以我们要让本地的服务通过外网访问,这里需要安装一个工具: ngork

brew install ngrok
复制代码

安装完成后通过下面的命令启动

ngrok http 8080
复制代码

正常启动后的界面应该是这个样子的

image.png

通过 http://176894cae96e.ngrok.io 就可以直接在外网访问到我们当前的本地项目了

接下来我们回到本地启动的 jenkins 界面当中,点击 系统设置 -> 系统配置 找到 GitHub ,点击右下角高级,注意这里有两个 高级 按钮,一个是 GitHub Server高级,一个是整个的 GitHub高级 按钮,旁边有一本小书的 icon

image.png

点击 高级 ,勾选 覆盖 Hook URL -> 为 GitHub 指定另外一个 Hook URL,点击这个高级后,页面可能会往下弹一下,滚动条滚回去就好

勾选后下方会显示出一个文本框,把默认的 localhost:8080 修改为上方通过 ngork 生成的一个外网链接,点击保存

image.png

保存后回到 github,点击当前项目中 Settings -> Webhooks -> Add webhookPayload URL 添加刚才复制出来链接

image.png

由于这里只是先讲解自动化构建的钩子,其实还有很多事件,但是暂时先不讲了,大家后期按照需求修改即可

添加完成后,会退回到 Webhooks 的列表页,这个时候状态是 pending,不过基本一刷新就是返回正常的状态了,或者通过启动 ngork 的终端内会获取到所有接口的请求

image.png

或者点击刚才添加的 Webhook 中,查看 Recent Deliveries

image.png

这个时候,就可以正常的通过 webhook 钩子通知到 jenkins

配置 Jenkinsfile

这个文件就是 jenkins 自动化构建时要跑的脚本文件,这里我简单的配置了一下,把它放到你当前项目的根目录中即可

pipeline {
    agent { docker 'node:latest' }
    stages {
        stage('Install') {
            steps {
                sh 'npm install'
            }
        }
        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }   
    }
}
复制代码

在回到 jenkins 服务器,继续点击左侧 系统设置 -> 插件管理 -> 可选插件,输入 docker

image.png

点击 Download now and install after restart 会跳转到安装插件页面,完成后点击 安装完成后重启Jenkins(空闲时)

image.png

点击后会显示即将关闭,并发起 jenkins 服务重启,如果没有自动重启的话手动刷新即可

在项目中通过 react 脚手架安装项目,这个百度一下自己安装就好,这个过程和 jenkins 暂时没关系

构建完成后,把代码推送到 git 远程库

打开 Blue Ocean,点击分支,选择初始化的 main 测试构建

image.png

这个时候等大概 5s 左右,通过 webhook 的钩子的事件,就会触发分支的构建

上图的红色状态是因为一开始我没有在 jenkins 内安装 docker 相应插件,然后会自动刷新构建状态

image.png

这说明通过 webhook 的钩子,通知到 jenkins 执行 jenkinsfile 文件内的管道任务

其实可以通过 jenkins 本身的构建列表去查看进度,但是 ui 实在太丑。。。

配置远程服务器并构建镜像

上面可以完整的进行项目打包了,现在我们需要登陆服务器进行构建镜像,下面是完整 jenkinsfile 的文件内容

pipeline {
    agent { docker 'node:latest' }
    stages {
        stage('Install') {
            steps {
                sh 'npm install'
            }
        }
        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }   
    }
}
stage('Docker build') {
    echo '尝试连接'
    docker.withServer('server ip', 'certificate id') {
        echo '连接成功'
        docker.build("jenkinsdocker/test-image:" + new Date().getTime(), "-f ./Dockerfile .")
    }
}
复制代码

这里的 server ip 就是服务器的 ipcertificate id 就是把当前服务器登陆的账号添加后生成的一个 id,在 系统管理 -> Manage Credentials -> 系统 -> 全局凭据 -> 添加凭据

添加上后会回到全局凭证列表,找到对应的 certificate id

image.png

在当前项目内添加对应的 nginxDockerfile 文件的内容

// Dockerfile

FROM nginx:latest

ADD ./build/ /usr/share/nginx/html/

COPY nginx/prod.conf /etc/nginx/nginx.conf

EXPOSE 80

STOPSIGNAL SIGTERM

CMD ["nginx", "-g", "daemon off;"]

复制代码
// nginx.conf

worker_processes  2;  ## Default: 1
# error_log  logs/error.log;
# pid        logs/nginx.pid;
worker_rlimit_nofile 8192;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
  include    /etc/nginx/mime.types;
  # include    /etc/nginx/proxy_params;
  # include    /etc/nginx/fastcgi.conf;
  index    index.html index.htm;

  # default_type application/octet-stream;
  # log_format   main '$remote_addr - $remote_user [$time_local]  $status '
  #   '"$request" $body_bytes_sent "$http_referer" '
  #   '"$http_user_agent" "$http_x_forwarded_for"';
  # access_log   logs/access.log  main;
  server_tokens off;
  sendfile     on;
  tcp_nopush   on;
  server_names_hash_bucket_size 128; # this seems to be required for some vhosts

  gzip on;
  gzip_disable "msie6";

  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_min_length 256;
  gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

  upstream api {
    server 127.0.0.1:8080;
  }
  server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location ~ ^/api/(.+) {
      rewrite /api/(.*) /$1 break;
      proxy_redirect          off;
      proxy_set_header        Host            $host;
      proxy_set_header        X-Real-IP       $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      client_max_body_size    10m;
      client_body_buffer_size 128k;
      proxy_connect_timeout   90;
      proxy_send_timeout      90;
      proxy_read_timeout      90;
      proxy_buffers           32 4k;
      proxy_pass              http://api;
    }
  }
}
复制代码

nginx.conf 配置测试其实不需要这么复杂,我是为了省一些不必要的时间出来,就直接从之前的项目拷了一份

代码提交,推送查看效果

image.png

正常的完成了镜像构建,下面就是需要我们登陆到自己的服务器内,通过 docker image ls 查看我们的镜像是否上传

image.png

该镜像已经成功的构建到了当前的项目当中,说明我们现在在本地通过 jenkins 可以完整的 接收通知、打包、构建

现在这样就基本上算是完成了,在服务器里执行 docker run -ti -p 80:80 1c24ca27fb24

尾声

到这里基本就结束啦,最后的命令执行其实可以在 jenkinsfile 里面做,我只是想告诉大家这样可以正常运行就好了

之前是我自己一步一步摸索做出来的,中间走了很多弯路,这篇文章就是我从0到1又自己演示了一遍实现的,可能也会有一些之前在本地改过的一些内容暂时想不起来了,如果大家有配置的有问题的时候,欢迎大家评论,我会找着解决办法并在文章内更新,希望这篇文章是一篇可以完整的实现自动化构建的文章

当前了这篇文章的技术点不是很难很复杂,目的是教一些没有使用过 jenkins 的朋友入门,接下来的扩展部分我也会继续更新,希望可以开源一整套完善的 CI/CD 流程,这个还希望大家一起督促,一起努力

最后,还希望大家和我多探讨一些之前对于前端技术的一些理念,一起让这个行业变得更好

实战篇 – 如何把性能优化的颗粒度做的更细

思想篇 – 通过 hooks 的出现,反思组件化开发存在的问题

公众号:全球互联网技术分享,关注后会发送入群二维码,大家进群一起探讨?

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享