前端工程化:保姆级教学 Jenkins 部署前端项目
DevOps
提到 Jenkins,想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。
DevOps Development
和 Operations
的组合,是一种方法论,并不特指某种技术或者工具。DevOps 是一种重视 Dev
开发人员和 Ops
运维人员之间沟通、协作的流程。通过自动化的软件交付,使软件的构建,测试,发布更加的快捷、稳定、可靠。
CI
CI 的英文名称是Continuous Integration
,中文翻译为:持续集成。
试想软件在开发过程中,需要不断的提交,合并进行单元测试和发布测试版本等等,这一过程是痛苦的。持续集成CI
是在源代码变更后自动检测、拉取、构建的过程。
CD
CD 对应两个概念 持续交付Continuous Delivery
持续部署Continuous Deployment
持续交付
提交交付顾名思义是要拿出点东西的。在 CI 的自动化流程阶段后,运维团队可以快速、轻松地将应用部署到生产环境中或发布给最终使用的用户。
从前端的角度考虑,在某些情况下肯定是不能直接通过自动化的方式将最终的 build 结果直接扔到生产机的。持续交互就是可持续性交付供生产使用的的最终 build。最后通过运维或者后端小伙伴进行部署。
持续部署
作为持续交付的延伸,持续部署可以自动将应用发布到生产环境。
Jenkins 安装
示例服务器为 阿里云 CentOS 服务器。安全组中增加 8080 端口 Jenkins 默认占用
Jenkins 安装大体分两种方式,一种使用 Docker 另一种则是直接安装,示例选择后者。不管使用哪种方式安装,最终使用层面都是一样的。 Linux 安装 , Docker 安装
点击查看Linux安装过程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
# 下载 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
如果最终 Jenkins
没有找到包而导致没有安装成功,检查第一步和第二部执行结果并重新执行。
可以使用 systemctl
命令管理 Jenkins 服务 systemctl
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
# 启动 Jenkins 服务
systemctl start jenkins
# 重启 Jenkins 服务
systemctl restart jenkins
# 停止 Jenkins 服务
systemctl stop jenkins
# 查看 Jenkins 服务状态
systemctl status jenkins
启动服务后访问服务器地址 + 8080 端口,Jenkins 默认为 8080 端口。
Jenkins 使用及 Freestyle 任务构建
首次进入使用 cat /var/lib/jenkins/secrets/initialAdminPassword
查看密码。
随后进入插件安装页面,暂时安装系统推荐插件即可。
然后创建用户
构建目标:拉取 github 代码
点击 新建 Item 创建一个 Freestyle Project
在 源码管理 处选择 git ,输入仓库地址,点击添加。
输入 github 账号和密码,这里的密码有时候可能会出现问题,可以使用 token
github 如何生成 token ?
配置只是一方面,同时服务器也要具备 git 环境。 yum install git
构建目标:部署到本机
部署前端项目肯定是离不开 nginx
的。 yum install nginx
。
安装完成后同样可以使用 systemctl
命令管理 nginx
服务。
nginx
具体配置这里就不说了。本示例项目中,静态文件托管目录为 /usr/share/nginx/html/dist
。
接着来到 Jenkins
这里。想要部署前端项目还需要依赖一个 Node
环境,需要在 Manage Jenkins -> Manage Plugins 在可选插件中搜索 nodejs
选择对应插件进行安装,安装完成后需要重启才会生效。
然后到 系统管理 -> 全局工具配置 中配置 Node
(吐槽:没有安装任何插件时系统管理以及其子页面全是英文,安装完插件后又变成了中文。这国际化不知道是系统原因还是它的原因 😂)。
随后去修改刚才创建的任务。在 构建环境 中会多出一个选项 Provide Node & npm bin/ folder to PATH
勾选即可。然后在 构建 中选择 增加构建步骤 -> 执行 shell 输入打包发布相关的命令。Jenkins
会逐行执行。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
npm install yarn -g
yarn install
yarn build
# 打包 build 后的文件
tar -zcvf dist.tar.gz dist/
# 删除 build 后的文件
rm -rf dist/
# 移动 build 后的压缩包到 nginx 托管目录下。
sudo mv dist.tar.gz /usr/share/nginx/html
# 进入托管目录下
cd /usr/share/nginx/html
# 解压
sudo tar -zxcf dist.tar.gz
# 删除压缩包
sudo rm -rf dist.tar.gz
- 由于项目构建时是在
Jenkins
的工作目录下执行脚本,会出现权限问题。导致即使使用了sudo
还会出现类似以下错误。
- 1
- 2
- 3
- 4
- 5
- 6
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 时不需要输入密码。
- 如果不使用
sudo
则会出现以下错误。
- 1
xxxxxxx: Permission denied
解决方案:修改 /lib/systemed/system/jenkins.service
文件。将 User=jenkins
修改为 User=root
,表示给 Jenkins
赋权限。修改配置文件后记得重启服务。
- 构建的过程中还可能出现以下错误
- 1
ERROR: Error fetching remote repo 'origin'
解决方案:由于需要构建的代码在 github
上面,这种错误表示拉取代码失败了,重试几次就可以了。
工作目录
上面提到一个很重要的概念就是 工作目录 在上面的 shell
默认就是在这里执行的。工作目录是由两部分组成。
/var/lib/jenkins/workspace/
类似于前缀吧。web-deploy
这个其实是上面构建任务的名字。
总结:Jenkins
的执行目录是 /var/lib/jenkins/workspace/web-deploy
。也就是说输入的每一条命令都是在这里面执行的。(搞清楚定位能避免好多问题,特别是前端的部署,就是打包,移动,解压很容易搞错路径。)
构建目标:侦听 git 提交到指定分支进行构建
来到
Jenkins
中选择 系统管理 -> 系统配置 找到Jenkins URL
将其复制。随后在尾部添加
github-webhook/
尾部斜杠一定不要丢。 整体结构大致为http://192.168.0.1:8080/github-webhook/
登录
github
需要集成的项目中添加webhook
。在Payload URL
中将上述内容填入。
- 然后修改
Jenkins
任务配置 构建触发器中选择 GitHub hook trigger for GITScm polling
由于在上面的源码管理中已经指定了main
分支,此时如果这个分支的代码有改动就会触发自动构建。
构建目标:部署到目标主机
在真实的开发场景中,
Jenkins
几乎不会和前端资源放到一个服务器。大多数情况下Jenkins
所处的服务器环境就是一个工具用的服务器,放置了一些公司中常用的工具。因此构建到指定的服务器也至关重要。
1,系统管理 -> 插件管理 搜索 Publish Over SSH
进行安装。
2,然后在系统管理 -> 系统配置中找到 Publish over SSH
点击新增,再点击高级,然后选中 Use password authentication, or use a different key
完成后可点击右下角 Test Confirguration
进行测试。
3,继续修改构建任务。先修改原有的构建脚本。因为要发布到远程,所以原有的发布命令要进行去除。
- 1
- 2
- 3
- 4
- 5
- 6
npm install yarn -g
yarn install
yarn build
# 只打包,然后删除文件夹。
tar -zcvf dist.tar.gz dist/
rm -rf dist/
4,选择构建后操作 -> Send build artifacts over SSH
Rransfer Set Source files
:要上传到目标服务器的文件。它是一个相对路径,相对于 Jenkins 的工作目录 由于上面的 shell 执行之后在工作目录中只有一个压缩包,so 直接写一个文件名即可。Remove prefix
:去前缀。假设此时打包文件在/var/lib/jenkins/workspace/web-deploy/assets/dist.tar.gz
,那么Rransfer Set Source files
则应该为assets/dist.tar.gz
,此时Remove prefix
配置为assets/
则可以去除这个前缀,否则会在目标服务中创建assets
。Remote directory
:远程的静态资源托管目录。由于配置服务器默认为/
,所以usr/share/nginx/html/
不用以/
开头。Exec command
:远程机执行shell
,由于配置服务器默认为/
, 所以 工作目录也是以/
开始。
执行成功后查看执行日志会有类似以下结果:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
SSH: Connecting from host [iZuf6dwyzch3wm3imzxgqfZ]
SSH: Connecting with configuration [aliyun-dev] ...
SSH: EXEC: completed after 202 ms
SSH: Disconnecting configuration [aliyun-dev] ...
# 如果 Transferred 0 file 则需要查看配置的路径是否正确。表示文件并没有被移动到远程主机中。
SSH: Transferred 1 file(s)
Finished: SUCCESS