前端CI篇—重生之前端已死转行运维

一、前言

声明不是小说哈!φ(>ω<*) 最近都在说什么“前端已死”,我觉得并没有啊,我问了我司的前端,他们都好好的,没有什么问题啊눈▂눈。大家不会在骗我吧。如果前端真的不行了,那就回家躺平吧,是在不行就地转行运维(开玩笑哈ヾ(◍°∇°◍)ノ゙)。

转回正题,我说的做运维不是真转运维哈!-_-||,这里只是学习了一小部分运维的工作———前端场景下GitLab 的 CI\CD,这一块我看好多大佬都说前端工程化不能少了这一块的知识,正好我司有这个需求,所以就跟着技术老大哥学习了一下怎么做前端这一块的 CI\CD,为了防止被埋到土里(指前端已死 ಠᴗಠ)。之前老早就有兴趣做这个了,但是一直没有动手,好在现在有机会来实现一下。目前已跑通 CI(持续集成)这一流程。

大致思路:

CI脑图

二、上手实操

由于是在内网开发,所以需要提前准备好不少东西,这里面也淌了不少坑,内网目前已经有 gitlab 服务,Docker 服务,Linux 系统使用的是 Debian,这些网上应该都可以找到相关的安装部署教程,这里就不一一详解了,对于一些与前端 CI 强相关的东西还是需要学习一下的,接下来我就按步骤来介绍吧

2.1 docker 镜像准备

这里主要有三个部分的镜像,nexus3、gitlab-runner、node。

  • sonatype/nexus3(nexus3 镜像)
    • Docker Hub查找 nexus 服务镜像:docker search nexus
    • 拉取对应的 nexus3 服务:docker pull sonatype/nexus3
    • 通过 docker images 查看镜像是否拉取到本地。
  • gitlab/gitlab-runner(gitlab-runner 镜像)
    • 查找鏡像:docker search gitlab-runner 查找符合自己要求的鏡像
    • 拉取鏡像:docker pull gitlab/gitlab-runner
  • node:18.15-bullseye-slim (打包所需 node 鏡像)
    • 拉取镜像:docker pull node:18.15-bullseye-slim

准备好上述镜像就可以开始了。

2.2 nexus3 服务搭建

nexus 是一个包管理服务,我们这里主要是用来管理 npm 包,首先介绍一下怎么安装配置:

  1. 镜像下载到本地后使用命令:docker run --rm -d -p 8081:8081 --privileged=true --name nexus3 sonatype/nexus3启动服务
  2. 用浏览器打开服务网址你的ip:8081,启动时间可能因为机器的优秀程度来决定等待时间,可以等等服务启动后再访问即可,没启动可能会找不到服务等一会即可,不要反复重新启动ヽ(´ ~`;)。
  3. 进入网页服务后它会提示你登录,会给你一个文件路径在命令终端中输入docker exec nexus3 cat /nexus-data/admin.password就可以获取到初始密码,/nexus-data/admin.password是网页提示的地址,这里按照实际提示替换,一般用户名是 admin,拿到密码后登录即可。
  4. 登录成功后会有一个初始化页面,需要注意这里需要重新设置密码,以及设置库访问权限,由于是内网使用所以我选择了无需校验Allow anonymous users to access the server允许任何人使用。
  5. 里面会初始化一些库,不需要可以全部删除,然后点击设置菜单的“Repository—>Create repository”,创建新的库,这里一共要创建三个,分别是 npm(proxy)、npm(hosted)、npm(group),三个库分别的作用就是 proxy 代理缓存,用于缓存公共资源到本地服务,hosted 是上传内部使用的框架及其包,group 则是分组,可以将前两个库聚合起来,直接访问 group 的 url 就可以获取两个库的资源包。
  6. 创建 npm(proxy)除了需要填写库名外,还需要填写Remote storage远程存储库,这里可以填写国内的 taobao 源https://registry.npmmirror.com/,如果本地找不到就拉取这个源的数据资源。
    nexus3配置
  7. 本地创建好 nexus 服务后就是使用了,点击仓库中 Browse,然后选择聚合库的 url 复制好以后,使用命令npm set registry http://192.168.43.150:8080/repository/npm-group/进行换源(可以使用npm get registry获取当前源),将你本机 npm 的访问地址替换到前面的命令中,这样就能使用本地的 npm 服务了,下载 npm 包就会先访问本地 nexus 服务,如果有直接加载,没有就远程获取然后本地服务缓存,下次就不用再访问网络上的存储库了。

如果内网使用这个库,在启动的时候还需要将库的数据映射到主机文件里面,到时候一起迁移再启动映射即可,这里不再赘述;在使用过程中,由于内网的问题,这里遇到了三个坑:

  1. 关于 npm 本地缓存与 nexus 服务缓存问题:本地缓存可以使用npm cache clean --force来清除,而 nexus 需要将上图中两个缓存时间设置成 0,不然的话有些依赖可能会映射一个路径而不是缓存到本地,具体不太清楚是什么原因造成的,打开库如果看到一个 json 文件映射,而不是存储的 tgz 文件,那么有可能就没缓存下来,这样会导致将 nexus 服务迁移到内网后缺少包而导致 CI 过程中安装 node_modules 失败,这个坑刚开始还想着错一个导一个,后面发现太多了,建议每次在外网下载好,每次下载前清除本地缓存,修改 nexus 缓存,检查好以后导进去避免缺包。
  2. Linux 系统下的问题:在外网之前用 windows 下载 npm 包,没有想到 linux 环境也需要一些包,比如 esbuild 这个,win 和 linux 环境下安装的打包依赖包有对应系统的版本,所以在外网使用 nexus 预加载包的时候,在 win 系统下面执行了npm i,在 linux 系统下也要执行一下npm i,因为 CI 过程中用的 docker 是 linux 镜像的 node 环境,所以需要对应系统的打包库。
  3. 不同系统英文字符大小写问题:关于这个问题,主要是 win 系统不区分大小写导致的,在 win 环境下我们进行前端开发,引用文件路径与实际不一致,有一两个大小写没注意,在 win 系统开发编译中可能没问题,但是在 linux 系统中大小写是区分的,所以 CI 过程中会提示检查错误,找不到对应文件,修改大小写使之对应即可。

2.3 gitlab-runner 服务启动及添加

GitLab Runner 是一个开源项目,用于运行您的作业并将结果发送回 GitLab。它与 GitLab CI 一起使用,GitLab CI 是 GitLab 随附的开源持续集成服务,用于协调作业。

我们这里使用 docker 来运行这项服务,为了运行服务方便这里编写了一个脚本,在此之前我们需要先获取 gitlab 上的 url、登录 token 等信息,将这些东西写入脚本,下次直接运行即可。

首先是获取 gitlab 上的 url 和 token,url 就是私服的部署地址,而 token 需要到具体的项目上获取,打开 gitlab 访问浏览器中自己的项目,然后选择侧边菜单栏的Settings->CI/CD,然后找到Runners点击旁边的Expand按钮展开,就能看到Project runners下面的 url 和 token 了,将这两个参数复制到下面脚本中后运行脚本即可,运行完成后就能在这个页面看到 runner 容器了。

具体脚本如下:

# 文件命名:start-runner.sh
# gitlab-runnede的bash启动脚本

GITLAB_URL="gitlab私服的地址"
REGISTRATION_TOKEN="私服项目的token"

# 启用网络使用本机网络 DNS根据需求自行设置
docker run --rm -d --net=host --name serve-runner \
  --dns 127.0.0.1 \
  -v /etc/gitlab-runner:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

echo "~~~~~~~~~~~~~~~~~~ gitlab-runner gegister info ~~~~~~~~~~~~~~~~~~"

# 这里注册gitlab相关信息,以及打包环境使用的docker镜像
docker exec -it serve-runner gitlab-runner register \
    --non-interactive \
    --url "${GITLAB_URL}" \
    --registration-token "${REGISTRATION_TOKEN}" \
    --executor "docker" \
    --docker-image node:18.15-bullseye-slim \
    --docker-network-mode "host" \
    --description "处理CI任务的gitlab runner的执行容器。" \
    --tag-list "fronted"

echo "~~~~~~~~~~~~~~~~~~ 已实例化的docker ~~~~~~~~~~~~~~~~~~"

docker ps -a

bash 脚本可能需要自己的实际情况进行修改,docker.sock 这个文件主要用于 docker 的镜像实例与主机通信,所以前面的地址是外部的 docker.sock 运行地址,后面是 docker 内部的地址;然后内网使用的时候,我们有自己的 dns 服务,所以专门指定了自己的 dns 服务地址,这个按自己需求设计即可;/etc/gitlab-runner这个地址主要是保存gitlab-runner register的注册信息,如果 docker 重启了,映射相同的文件就会使用之前注册的信息不用重复注册,这里我直接写在脚本里面,所以每次运行不用文件映射保存也可以。

之后的.gitlab-ci.yml 文件中会用到 node 镜像需要提前在这里注册一下,我这里主要设置了对应所需要的 docker 镜像名字,以及网络连接方式。gitlab 的信息在开头使用了变量,直接替换对应的信息即可。

由于平时不咋使用 linux 这种系统,所以有几个小问题需要注意一下,写好 bash 脚本后,需要进行提权(例:sudo chmod 755 start-runner.sh),然后直接执行文件即可(./start-runner.sh),执行完成后可以查看输出信息判断运行注册是否成功,docker ps -a 可以查看正在运行的 docker。

runner 自动添加后,跑 yml 脚本可能会有失败的情况,这里还需要登录 gitlab 管理员账户设置一下 runner 配置,点击右上角菜单选择Admin->CI/CD->Runners,然后打开对应的 runner 设置,Run untagged jobs 这行一定要勾上,因为 runner 和 job 匹配的规则是,runner 的 tag 和项目的 tag 要相同。所以,如果不把这个选项加上会不触发 runner 导致 CI 过程无法进行。

2.4 .gitlab-ci.yml 文件编写

直接在项目根目录添加一个.gitlab-ci.yml的文件,这个文件是 gitlab 的 CI 执行的脚本,按照自己需求编写打包流程后提交即可,可以先把写好的内容在 gitlab 上的 CI Lint 中进行测试,没问题后再提交。

下面给出我写的一个简单打包例子:

# 打包执行docker镜像环境
image: node:18.15-bullseye-slim

# pipeline 流水线
stages:
  - install
  - build

# 缓存
cache:
  paths:
    - node_modules/

# 安装包预加载
add-package:
  stage: install
  script:
    - echo "================== 安装node_modules ! !=================="
    - npm set registry http://nexus.dev.ac.cn/repository/npm-group/
    - echo "================== node_modules 加载完毕!!=================="

# dev 开发分支构建
build-dev:
  stage: build
  only:
    - dev
  script:
    - echo "================== dev-开发-分支构建=================="
    - npm run build
    - echo "================== dev-开发-构建结束=================="
  artifacts:
    expire_in: 1 week
    name: dev-pkg
    paths:
      - dist/

# main 生产分支构建
build-production:
  stage: build
  rules:
    - if: "$CI_COMMIT_BRANCH == 'main'"
  script:
    - echo "==================main-生产-分支构建=================="
    - npm run build
    - echo "==================main-生成-构建结束=================="
  artifacts:
    expire_in: 1 week
    name: production-pkg
    paths:
      - dist/

完成上述 yml 脚本后,在 gitlab 上 CI Lint 检测没问题后即可提交,主要功能是检测两个分支 dev 和 main 分支,对应的是开发和生产环境,每个分支进行代码提交后会分别进行打包处理,其中image是我们之前在 runner 注册的时候的 docker 镜像,它是整个脚本执行流程的运行环境,一共有两个流水线,分别是 install 和 build,在 install 阶段我们使用内网的 nexus3 源下载所需要的 npm 包,下载完成后进行了缓存处理,在 build 阶段根据推送的分支进行项目构建打包处理,最后生成打包好的项目,在 artifacts 的 paths 中进行匹配,将需要的文件进行整合处理,最后可以在 GitLab 的 Pipelines 中下载到对应的压缩产物。其中 expire_in 属性设置了产物保存时间为一周,name 指定了下载压缩包的名字。

三、总结

目前为止就完成了一个简单的前端 CI 流程,整体而言其实不算太难,但是之前没学过 docker,Linux 系统也使用的比较少,所以还是花了不少时间在这上面折腾,尤其是闭网环境下,还有各种缓存问题,配置环境上主要还是网络上设置,以及对于整个过程需要配置系统细节参数的把握程度,总的来说就是需要全方面的了解这些知识,当然用到啥学啥,虽然可能有点困难,但是至少不会拘泥于前端开发一块小地方,以后也可以尝试转运维 ─━ _ ─━✧,感觉也学到了不少东西,加油吧!

CD 指的是持续部署和持续交付,这里主要还是写脚本,简单点的话直接打包完成后把生成物放到服务器上的指定目录,可以是 Nginx 服务器的站点目录,也可以是其它容器服务的站点;难一点的话就是整个服务重新跑一个 docker 的 Nginx 服务或其他 web 服务器,然后把代理等配置一起写到脚本里面,每次打包生成可以根据需求配置一些代理相关设置,然后重新部署发布。这里等实现以后有空再写一篇关于 CD 相关的文章吧。

感谢您的耐心阅读,如果有帮助不妨帮我点一个小小的赞,表示支持,感激不尽( • ̀ω•́ )✧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZERO丶X

托马斯回旋360°飞旋感谢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值