开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
什么是自动化部署
我接触到的自动化部署概念最早是在 Vercel 上提供的,Vercel 可以提供和 github 联动的功能,通过和你自己的 github 上的某个库建立‘链接’,当你 commit 到 github 远程库时就可以自动部署,Vercel 会帮你完成以下操作(例子为一个 Webpack 项目,仅限 Web 前端,如有遗漏望补充)
Webpack打包(默认是项目package.json的打包命令)- 打包文件迁移到
Vercel的服务器上(dist目录下的文件) - 部署网站(
Vercel使用的Nginx还是Apache我就不知道了,应该是用的Nginx)
另一个自动化部署概念是在实习时接触的,公司称之为流水线,它的作用和 Vercel 差不多,不过会多了两个步骤
ESLint校验代码- 重新安装依赖
Webpack打包(默认是项目package.json的打包命令)- 打包文件迁移到
Vercel的服务器上(dist目录下的文件) - 部署网站(
Vercel使用的Nginx还是Apache我就不知道了,应该是用的Nginx)
现在自动化部署的概念炒的火热,主要是它通常还可以和 Serverless 绑定在一起,Serverless 意思是无服务器,其实就是托管应用程序到 Serverless 服务提供商的服务器上,像一些小微公司可以直接托管网站、小程序,完全不用买服务器(为啥不买服务器,因为 Serverless 便宜呀)
像 Serverless、自动化部署和它们的可视化界面就不多介绍了,但我要说腾讯云在这方面做的很烂,相反 Azure 和 Vercel 做的就很好
普通部署
说完了自动化部署那么我们平常的普通部署是怎么做的呢?以一个 nodejs 的普通接口为例(基于 express-generator 生成的项目)
# npm v5.2.0 以上版本
npx express --no-view --git
git init
npm install
执行上面的命令后得到下面的目录结构
├── .git/
├── bin/
├── node_modules/
├── public/
├── routes/
├── .gitignore
├── app.js
├── package-lock.json
└── package.json
- 第一步,在宝塔安装
pm2如果你没有的话(pm2会自动安装nodejs和npm)
- 第二步,在服务器找到一个地方放你的文件,这里项目比较小,我就直接丢上去了(一般使用
zip压缩文件,或者在服务器上重新执行npm install)
- 第三步,在你的
PM2面板里面添加项目
- 第四步,提交查看效果,是否符合本地运行预期
后续重新更新部署怎么办?很简单,将更新的文件覆盖掉原文件,在 PM2 重启一下就行了
但是如果我想本地 git 提交代码到远程库的时候能够顺便部署行不行呢?看下面的操作
自动化部署
本篇文章实现的自动化部署是基于 github 的 Webhooks 和宝塔的 WebHook 实现
那如何将上面的普通部署改成这个自动化部署呢?
- 第一步,在
github上创建对应的库(反正又不要钱,随便创)
- 第二步,在服务器拉取项目并在在
PM2添加项目(同普通部署) 并查看id信息
cd /www/temp
git clone git@github.com:pandoralink/auto-deploy.git
cd auto-deploy
npm install
# 查看 Linux 的 PM2 项目 id 信息
pm2 list
id 信息如下图
在 Linux 操作 git 添加公钥私钥到远程仓库(github/gitee)可以参考 服务器上的 Git - 生成 SSH 公钥 和 远程仓库 - 远程仓库
- 第三步,安装宝塔
WebHook插件
- 第四步,添加宝塔
WebHook规则
- 第五步,获取宝塔
WebHookURL
- 第六步,配置
github的WebHooks
注意,content-type 需要选择 application/json,否则 github 请求此 URL 时,宝塔会返回 403 错误
配置结果如图
测试修改一下 public/index.html 的内容,并 push 到 github 远程仓库
成功修改并部署成功,结果如下
填坑
2023/09/25 更新
自动化部署算是我反馈比较多的一篇文章,其实这不是没有原因的,因为在自动化部署这块出现了问题,原有的自动部署在静态文件是没有问题的,因为对于 pm2 启动的进程来说,都是拿的相对路径并返回,比如
git pull // 更新 public | dist 这些静态文件
请求服务
nodejs 服务返回对应路径的文件 // 只要路径对应的文件更新就会自动更新
但是对于接口一类文件,比如 route/controller,这些不是文件更新了就行,还需要 pm2 restart 才可以,因为 pm2 执行的时候会用缓存(其实就是把硬盘的内容放到内存),所以需要 pm2 restart,重点来了
pm2 restart 未执行成功原因
这可能和宝塔的 webhook 的执行用户有关
在测试中,虽然我用 whoami 打印出来是 root,但实际表现和我用 root 用户登录执行的结果不一致
最终解决方案,是使用使用 su - root -c "pm2 restart ${pid}",解决了这个问题
令人疑惑的解决方案,自己已经是 root 却还要使用 su - root -c 这个命令指定 root 角色执行指定命令,有好奇心的同学可以拿这篇文章去问问宝塔官方~
最终的宝塔脚本为
echo $(date "+%Y-%m-%d %H:%M:%S") 开始部署
cd /www/wwwroot/nodejs/auto-deploy
git pull
su - root -c "pm2 restart ${pid}" # ${pid} pm2 项目 id, e.g. pm2 restart 5
echo $(date "+%Y-%m-%d %H:%M:%S") 重启成功
PS: 不要使用 pm2 项目的名称,不能成功启动
快去试试这个前后端都能够重新部署的全新版本吧!
总结
相比于 Vercel 还是我实习公司的流水线,文章中实现的自动化部署还是过于简陋,成熟的自动化部署拥有可视化界面,完善的日志,部署进度条,这些都是需要很多努力和经验去实现的,最后给出自动化部署的流程图