内网jenkins+frp内网穿透+部署前端项目至阿里云oss

1,702 阅读7分钟

背景

公司有一台闲置电脑主机,被我重装成CentOS7系统,并且在上面部署了Jenkins,主要用于安卓APP发布,如今公司有一项新的业务,需要将阿里云code的前端项目打包部署到阿里云OSS,做静态页面,下面记录一下做法和步骤。

步骤

一、创建阿里云oss,配置静态主页

  1. 首先我们创建新的bucket,作为DNS域名转发的地址;
  2. 设置公共读权限;

1655262443310.png

  1. 设置静态页面选项,否则浏览器访问的时候不会展示index.html,会下载该文件。

1655262531879.png

二、安装NodeJS

对于前端项目,他们也有专属的打包命令,就像android的gradle,java的maven,对于前端项目我们也需要事先安装该包:安装包地址:nodejs.org/en/download…

image.png 将下载好的安装包上传至内网的linux服务器,并执行安装:

[root@localhost ~]# tar -xf node-v16.13.1-linux-x64.tar.xz
[root@localhost ~]# mv node-v6.11.2-linux-x64 /usr/local/nodejs
[root@localhost ~]# cd /usr/local/nodejs    # 本次我安装在了 /usr/local 下
[root@localhost nodejs]# ln -s /usr/local/nodejs/bin/npm /usr/local/bin
[root@localhost nodejs]# ln -s /usr/local/nodejs/bin/node /usr/local/bin
[root@localhost nodejs]# node -v		# 验证
[root@localhost nodejs]# npm -v			# 验证
[root@localhost nodejs]# npm install -g cnpm -registry=https://registry.npm.taobao.org # 设置淘宝的仓库路径

三、jenkins控制台进行配置

1、设置环境变量

在Jenkins控制台进入 Manage Jenkins ,再进入 Global Tool Configurationimage.png

2、安装必要的插件

进入 Manage Jenkins 里面的 Plugin Manager

首先安装 Generic Webhook Trigger ,该插件的作用是push代码之后自动触发构建发布。

然后安装 NodeJS Plugin ,该插件的作用能够在 构建环境 里面添加:Provide Node & npm bin/ folder to PATH。

接下来安装 Qy Wechat Notification ,该插件的作用是将构建开始、构建失败、构建成功之类的通知发送到企业微信。

最后我们要安装 Aliyun OSS Uploader ,该插件的作用是能够发布到OSS。

四、Jenkins整体流程

1、新建自由风格的流水线

2、General

本次全部留空,具体作用自行了解。

1655263427706.png

3、源码管理

本次拉取阿里云代码使用的是SSH密钥拉取的,HTTPS方法当初摸索的时候不能用,不再细究原因和做法,下面的分支就是本流水线拉取的分支。

1655263665328.png

4、构建触发器(重点)

这里就是做到push代码到release分支之后,自动构建的关键所在,我们在前面安装了 Generic Webhook Trigger 插件,这里就会多出该选项,对该选项打勾:

image.png

a、Post content parameters

点击 Post content parameters 下面的新增:

image.png 按照下面的内容填入,并对JSONPath打勾。Value filter、Default value不填。具体含义不说,自行了解。

Name of variable:ref

Expression:$.ref image.png

b、Token

Header parameters、Request parameters不选,Token可以使得我们的webhook更加安全,可以自己随意指定编辑一个Token值。例如本次指定了 123456abc 。下面的 Token Credential 不选。

1655286157676.png

c、Cause

对 Print post content 和 Print contributed variables 打勾,其他保持默认或留空。

image.png

d、Option filter

按照下面的选项进行写入,这里需要注意,Expression里面的release,就是说只有代码push到release分支才会触发构建。根据不同分支名可对其进行修改。

Expression:^(refs/heads/release)$

Text:$ref

image.png

5、构建环境

构建环境这里我们要选择 Delete workspace before build starts ,即构造前删除工作目录,这样可以保证我们每次构建都是拉取的最新的代码;并且前面我们安装了 NodeJS Plugin 模块,这里会多出 Provide Node & npm bin/folder to PATH 选项,对该选项打勾,对其子选项皆保持默认。

image.png

6、构建

本次的构建使用的是 Execute shell ,即linux命令。这里的命令的意思是先进入该项目的工作目录,然后执行构建命令,构建命令可以询问开发同事得知。 1655275496974.png

7、构建后操作

构建后操作需要添加两个,企业微信通知 和 阿里云OSS上传。

这里有构建后删除工作环境的选项,但是不建议在这里选,还是建议在上面的构建环境,在构建前进行删除。因为推送到阿里云oss这个过程如果没有结束,就会和删除工作目录起了冲突,导致任务失败。

a、企业微信通知

我们前面安装了 Qy Wechat Notification 插件,该插件可以提供该选项,使用方法就是我们在企业微信创建一个群聊(至少三个人),然后在里面添加一个群机器人,添加之后会生成一个webhook地址,该webhook地址就需要填写在这里,作为通知地址;通知UserID就是群机器人通知时@的人,手机号码我虽然填写了但是没有收到过什么消息,不确定是否是因为内网搭建jenkins的原因。

image.png

b、阿里云OSS上传

我们前面安装了 Aliyun OSS Uploader 该插件,该插件可以提供 阿里云OSS上传 选项。按照下面解释填写:

  1. Endpoint:即阿里云地域,这里是深圳,即 oss-cn-shenzhen.aliyuncs.com
  2. AccessKeyId、AccessKeySecret 两者根据我们阿里云账户的令牌填写 ;
  3. BucketName:即我们该文章第一步创建的oss的bucket的名字。
  4. 本地路径:/dist, 工作下的根目录开始算 ,例如 :图中目录 /dist 指向的工作目录是 /var/lib/jenkins/workspace/${JOB_NAME} 下的dist,完整目录是/var/lib/jenkins/workspace/${JOB_NAME}/dist,即上传dist下面的所有内容。
  5. 远程路径:/ ,例如图中的”/“,指向的是阿里云oss的bucket的根目录。

1655276883180.png

五、jenkins内网穿透

到这里上面为止,Jenkins 就已经全部配置完毕了。因为我们的内网Jenkins服务器地址是192.168.0.200,服务端口是8080。所以根据构建触发器下面的提示,已经知道我们的push代码触发构建的webhook地址是:

http://192.168.0.200:8080/generic-webhook-trigger/invoke?token=123456abc

我们的代码库是在阿里云code,所以就要将 Jenkins 服务做内网穿透,将上面链接的内网ip和端口替换为外网可访问的地址。

内网穿透可以选择ngrok,但是免费的ngrok会不定期强制更换地址,这就导致我们的webhook会不断更改,这很不方便,因此我们使用frp,同样起到内网穿透的效果。当然其他的内网穿透工具也可以。

frp下载地址:github.com/fatedier/fr…

frp的原理大致就是将内网服务的端口,绑定在有外网ip的服务器的某个端口上,然后通过访问该外网服务器的端口,间接访问到内网服务的端口。因此这需要我们有一台有外网ip的服务器。

1、安装frp

服务端(外网服务器)和客户端(内网jenkins服务器)都解压安装frp,服务端是frps,客户端时frpc。下面的命令在两端各执行一次。

[root@localhost ~]# tar -xf frp_0.43.0_linux_amd64.tar.gz
[root@localhost ~]# ll frp_0.43.0_linux_amd64
-rwxr-xr-x 1 1001 121 10936320 5月  27 16:31 frpc		# 客户端程序
-rw-r--r-- 1 1001 121    10934 5月  27 16:35 frpc_full.ini		# 客户端完整配置文件
-rw-r--r-- 1 1001 121      126 5月  27 16:35 frpc.ini		# 客户端简易配置文件
-rwxr-xr-x 1 1001 121 14032896 5月  27 16:31 frps		# 服务端程序
-rw-r--r-- 1 1001 121     5560 5月  27 16:35 frps_full.ini		# 服务端完整配置文件
-rw-r--r-- 1 1001 121       26 5月  27 16:35 frps.ini		# 服务端简易配置文件
-rw-r--r-- 1 1001 121    11358 5月  27 16:35 LICENSE

2、修改配置文件

服务端(外网服务器)

[root@localhost frp_0.43.0_linux_amd64]# vim frps.ini

[common]
bind_port = 7000	# 该进程在服务器所占的端口
vhost_http_port = 8080	# 访问的外网服务器的端口

[root@localhost frp_0.43.0_linux_amd64]# ./frps -c ./frps.ini		# 以简易配置文件启动外网服务端

[root@localhost frp_0.43.0_linux_amd64]# ss -ntulp | grep 7000          # 查询该进程是否启动
tcp    LISTEN    0    128    [::]:7000    [::]:*    users:(("frps",pid=10883,fd=3))

客户端(内网服务器)

[root@localhost frp_0.43.0_linux_amd64]# vim frpc.ini

[common]
server_addr = 47.106.xxx.xxx	# 外网服务器ip
server_port = 7000	# 服务端的frps端口
[web]
type = http
local_port = 8080	# 本地服务端口(jenkins端口)
custom_domains = 47.106.xxx.xxx	   # 解析到公网IP上的域名,这里没有添加解析记录,所以直接用ip

[root@localhost frp_0.43.0_linux_amd64]# ./frpc -c ./frpc.ini		# 以简易配置文件启动内网客户端

这时候我们的客户端jenkins服务8080端口已经和外网服务端的8080端口绑定。访问外网服务器8080端口就可以访问到我们内网jenkins服务。那么webhook地址就变为了:

http://外网ip:8080/generic-webhook-trigger/invoke?token=123456abc

此时该webhook地址就可以放入到阿里云code的webhook里面,当我们push代码到release分支的时候,就会触发该流水线构建。

3、后台运行frp

我们的客户端和服务端运行了frpc和frps,那我们就不能关闭该终端了,关掉的话,服务也会关掉。因此为了方便管理和运行,可以编辑service文件:

a、编辑服务端service文件(外网服务器)
[root@localhost ~]# vim /lib/systemd/system/frps.service

[Unit]
Description=frps service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
#启动服务的命令(此处写你的frps的实际安装目录)
ExecStart=/root/frp_0.43.0_linux_amd64/frps -c /root/frp_0.43.0_linux_amd64//frps.ini
[Install]
WantedBy=multi-user.target
b、编辑客户端service文件(内网服务器)
[root@localhost ~]# vim /lib/systemd/system/frpc.service

[Unit]
Description=frpc service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
#启动服务的命令(此处写你的frpc的实际安装目录)
ExecStart=/root/frp_0.43.0_linux_amd64/frpc -c /root/frp_0.43.0_linux_amd64/frpc.ini
[Install]
WantedBy=multi-user.target
c、服务端管理命令
systemctl start frps		# 启动frps 
systemctl enable frps		# 再打开自启动
systemctl  disable frps		# 关闭开机自启动
systemctl restart frps		# 重启应用
systemctl stop frps		# 停止应用
systemctl status frps		# 查看应用的日志
d、客户端管理命令
systemctl start frpc		# 启动frpc 
systemctl enable frpc		# 再打开自启动
systemctl  disable frpc		# 关闭开机自启动
systemctl restart frpc		# 重启应用
systemctl stop frpc		# 停止应用
systemctl status frpc		# 查看应用的日志

使用这种方法关闭终端就不会导致服务关闭。

最后

到这里就全部实现push到代码库release分支的时候,jenkins自动拉取代码,自动打包,自动部署到阿里云oss。本文描述的的是我实现的方法,算是实现功能的基本操作,并未过多给与各选项解释,具体含义可以自行了解,有何错误和不足也欢迎指出。