从零搭建jenkins+nginx自动化部署

696 阅读5分钟

前言

提到 Jenkins,首先会想到的概念就是 DevOpsCI/CD

DevOpsDevelopmentOperations 的组合,是一种方法论,DevOps 是一种重视开发人员和运维人员之间沟通、协作的流程。通过自动化的软件交付,使软件的构建、测试、发布更加快捷、频繁、可靠。

CI

CI 的英文名称是Continuous Integration,也就是持续集成的意思。

假如我们在开发过程中不断的提交、进行单元测试、发布测试版本,这个过程无疑是极其痛苦的,不管是运维还是开发都需要花费大量时间和精力在这上面。持续集成CI是在源代码变更后自动检测、拉取、构建的过程。

CD

CD 对应的是持续交付 Continuous Delivery 和持续部署 Continuous Deployment

持续交付

CI 自动化流程阶段后,运维团队可以快速、轻松地将产出交付给到最终使用的用户。

从前端的角度来看就是可持续性交付构建出的产物给到运维或者后端进行部署

持续部署

持续交付的延伸,可以自动将应用发布到目标服务器

前置要求

  1. 云服务器ECS一台(目前我使用的是CentOS+2核8G)
  2. Linux基础操作知识

连接服务器

ssh -p 用户名@服务器ip地址

安装Nginx

# 下载nginx
yum install nginx
# 查看是否安装成功
nginx -v
# 设置为在系统启动时自动启动
systemctl enable nginx

执行service nginx start 启动服务

此时直接访问服务器80端口就可以看到nginx的首页,此时首页的文件路径是/usr/share/nginx/html/index.html ,假设我们后续部署的文件地址是/usr/share/nginx/html/dist/index.html,那么我们需要修改配置文件去调整首页的地址

获取配置文件路径

# 查看配置文件地址
nginx -t

编辑配置文件

# 编辑配置文件 路径是配置文件的地址
vim /etc/nginx/nginx.conf

将80端口的配置稍微调整即可

location / {
    # 前端代码包地址
    root   /usr/share/nginx/html/dist; 
    index  index.html index.htm;
}

修改完配置后执行service nginx reload 刷新配置即可

安装Git

yum install git

安装Jenkins

# 下载 Jenkins 资源
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo
# 获取并导入信任 的包制作者的秘钥
sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
# 升级 yum 源中的所有包
sudo yum upgrade
# Jenkins 依赖于 java 所以需要安装 JDK
sudo yum install java-11-openjdk
# 安装 Jenkins
sudo yum install jenkins

安装完成后可以使用systemctl管理jenkins服务

# 启动 Jenkins 服务
systemctl start jenkins
# 重启 Jenkins 服务
systemctl restart jenkins
# 停止 Jenkins 服务
systemctl stop jenkins
# 查看 Jenkins 服务状态
systemctl status jenkins
# 设置开机启动
systemctl enable jenkins

jenkins默认使用8080端口号,启动服务后访问服务器地址+8080端口号

初始化jenkins

首次访问会显示以下内容

需要在终端运行cat /var/lib/jenkins/secrets/initialAdminPassword 查看密码

安装插件

随后进入插件安装页面,建议安装系统推荐插件。

安装完成之后即可创建账号

选择 Manage Jenkins -> Manage Plugins选项,安装以下插件:

  • NodeJS
  • Publish Over SSH(用于远程部署)
  • Git Parameter(构建时选择参数)
  • Role-based Authorization Strategy(角色权限管理)

安装NodeJs

选择Manage Jenkins -> Global Tool Configuration -> NodeJS 选择安装对应的nodejs版本并保存,如果源比较慢就使用国内的地址:https://npm.taobao.org/mirrors/node/

配置ssh信息

选择Manage Jenkins -> Configure System 填写相关配置

点击测试连接是否成功

配置全局凭据

点击新增凭据

添加git仓库的账号密码,方便后面复用

创建项目

选择 新建Item -> 创建一个自由风格的软件项目

设置仓库配置

设置构建参数

General中,勾选This project is parameterized选项。

新增Git参数

设置参数名称Branch,参数类型为分支 ,并设置源码管理->Git -> Branches to build值为${Branch}

screenshot-20230413-173844.png #### 新增`Choice Parameter`

设置参数名称为Env,可选项为dev1dev2 ,在后续构建脚本可以通过${Env}获取到对应的值。

设置NodeJS版本号

编辑构建命令

# 切换源
nrm use taobao
npm i
# 构建 ${Env}就是我们上面Chioce Parameter设置的值
npm run build --env=${Env}
# 将构建产物打包
tar -zcvf dist.tar.gz dist/
# 删除构建产物
rm -rf dist/

由于项目构建时是在 Jenkins 的工作目录下执行脚本,可能会出现权限问题。导致即使使用了 sudo 还会出现类似以下错误。

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:    
  
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.

解决方案:在 /etc/sudoers 文件中增加 jenkins ALL=(ALL) NOPASSWD:ALL 表示在执行 sudo 时不需要输入密码。

添加构建后操作

构建完成

构建完成后,访问ip+80端口就可以看到打包出来的页面

其他配置

飞书机器人推送

创建飞书群并添加群机器人

创建脚本文件

在服务器任意位置创建推送脚本,并将上一步生成的webhook密钥填写进脚本内(也可以将webhook和密钥作为参数传入)

#! /usr/bin/python3
#-*- encoding: utf-8 -*-
 
import sys
import requests
import time
import hmac
import base64
import hashlib
from datetime import datetime
 
 
class JenkinsInfo(object):
    def __init__(self, feis_webhook, feis_secret, job_url, job_name, build_number):
        self.feis_webhook = feis_webhook
        self.feis_secret = feis_secret
        self.currenttime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self.timestamp = int(time.time())    # datetime.timestamp(datetime.now())
        self.JOB_URL = job_url
        self.JOB_NAME = job_name
        self.BUILD_NUMBER = build_number
 
    def gen_sign(self):
        # 拼接timestamp 和 secret
        string_to_sign = '{}\n{}'.format(self.timestamp, self.feis_secret)
        hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()
 
        # 对结果进行base64处理
        sign = base64.b64encode(hmac_code).decode('utf-8')
        return sign
 
    def feis_post(self):
        method = 'post'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400',
            'Content-Type': 'application/json'
        }
        json = {
            "timestamp": self.timestamp,
            "sign": self.gen_sign(),
            "msg_type": "interactive",
            "card": {
                "config": {
                    "wide_screen_mode": True,
                    "enable_forward": True
                },
                "elements": [{
                    "tag": "div",
                    "text": {
                        "content": "项目名称:" + JOB_NAME + "\n构建编号:第" + BUILD_NUMBER + "次构建\n运行时间:" + self.currenttime,
                        "tag": "lark_md"
                    }
                }, {
                    "actions": [{
                        "tag": "button",
                        "text": {
                            "content": "查看报告",
                            "tag": "lark_md"
                        },
                        "url": JOB_URL,
                        "type": "default",
                        "value": {}
                    }],
                    "tag": "action"
                }],
                "header": {
                    "title": {
                        "content": JOB_NAME + " 构建报告",
                        "tag": "plain_text"
                    }
                }
            }
        }
        res = requests.request(method=method, url=self.feis_webhook, headers=headers, json=json)
        print(res, "=======>>", res.json())
 
 
if __name__ == "__main__":
    feis_webhook = r"飞书机器人webhook地址"
    feis_secret = "机器人密钥"
 
    JOB_URL = sys.argv[1]
    JOB_NAME = sys.argv[2]
    BUILD_NUMBER = sys.argv[3]
 
    # JOB_URL = JOB_NAME = BUILD_NUMBER = "123"
 
    t = JenkinsInfo(feis_webhook, feis_secret, JOB_URL, JOB_NAME, BUILD_NUMBER)
    t.feis_post()

调用脚本

在项目构建完成后调用,假设我们上一步脚本的地址为/usr/share/jenkins/feishutongzhi.py

python3 /usr/share/jenkins/feishutongzhi.py $JOB_URL $JOB_NAME $BUILD_NUMBER

Git钩子触发构建任务

  1. 安装Gitee插件
  2. 修改项目配置-> 构建触发器 -> Gitee webhook触发构建
  1. 生成密码
  1. 前往gitee项目仓库 -> 管理 -> WebHooks -> 添加webHooks

Tips: 如果是Gitlab的话就安装Gitlab插件,其他配置基本一致