背景 #
在实现前后端部署之后,后续部署如果每次都手动的将文件传到服务器上面,例如在传统的开发场景中,我们需要手动打包,之后将打包的产物交给运维人员,运维人员在服务器上替换文件,这样效率不够高,并且负责的项目多了之后,可能会造成混乱。
这时候,需要使用一些自动化的流程,去帮助我们实现打包和部署的自动化,这里我用到了 github actions,它免费,流程较为简单,可以作为自动化部署的入门级流程,并且有很多三方工具可以使用,避免造轮子。
前端(React)的自动化部署 #
其他简单实现方式(手动) #
- 利用 sftp 或 ftp 工具上传文件到服务器的指定目录
- 利用 node 脚本编写上传命令在代码上传后执行
以 node 脚本为例
- 在 package.json 的 scripts 中增加文件上传
"upload": "scp dist xxx@xxx:/var/www/html"- 执行命令
npm run uploadgithub actions #
- 在 github 仓库中选择 actions 创建自己的 actions
- 书写自己的 actions,字段解释以及教程可参考阮一峰的教程 🔗
name: CI/CD
on:
push:
branches:
- main # 只在master上push触发部署
jobs:
build:
runs-on: ubuntu-latest # 在虚拟机中执行任务
steps:
- name: Checkout # 拉取代码
uses: actions/checkout@v3
- name: Set Node.js 18.x # 指定nodejs版本
uses: actions/setup-node@v3
with:
node-version: "18.x"
- name: Install dependencies # 下载依赖
uses: borales/actions-yarn@v4 # 使用yarn才加这个一般直接npm install
with:
cmd: install
- name: Build #开始打包
uses: borales/actions-yarn@v4 # 使用yarn才加这个一般直接npm build
with:
cmd: build
- name: Deploy to Server
uses: burnett01/[email protected] # 这里是第三方库,用于连接服务器并执行文件同步操作
with:
switches: -avzr --delete
path: dist/
remote_path: /home/frontend/weather-search
remote_host: ${{ secrets.SSH_HOST }}
remote_user: ${{ secrets.SSH_USERNAME }}
remote_key: ${{ secrets.SSH_PRIVATE_KEY }}-
添加 secrets 变量
可以看到在上面的脚本中,使用了 secrets 变量,避免了在脚本中出现明文导致安全问题,尤其是直接出现 ssh 的私钥
-
触发 github actions 检查是否能成功执行
后端(koa)自动化部署 #
和前端比较类似,action 部分都差不多,也可以使用简单方式进行,需要注意的是,对没有必要放在服务器上的文件进行过滤
name: deploy-server
on:
push:
branches: main
jobs:
deploy-server:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set Node.js 18.x
uses: actions/setup-node@v3
with:
node-version: "18.x"
- name: Install dependencies
run: npm install
- name: Deploy to Server
uses: burnett01/[email protected]
with:
switches: -avzr --delete
path: /
remote_path: /home/ubuntu/project/backend/weather-search-server
remote_host: ${{ secrets.SSH_HOST }}
remote_user: ${{ secrets.SSH_USERNAME }}
remote_key: ${{ secrets.SSH_PRIVATE_KEY }}
EXCLUDE: ".git, .gitignore" # 伪码,ssh deploy那个插件才有这个参数唯一的区别在于前端项目使用了 nginx 反向代理,当前端文件变更时,nginx 加载的文件就是最新的文件,而后端是通过管理进程启动的服务,文件更新后,需要手动重启一次服务
实现自动重启服务 #
以 pm2 为例
- 在服务器的项目目录中增加
ecosystem.config.js
module.exports = {
apps: [
{
name: "server", // app name
script: "./app.js", // 启动执行文件
cwd: "/home/project/backend/", // script 执行目录
watch: [
// 监听文件路径
"app.js",
"config",
"controller",
"utils",
"models",
"router",
"views",
],
watch_delay: 1000, // 文件变化后,延迟重启时间
ignore_watch: ["node_modules"], // 监听忽略路径
},
],
};- 执行
pm2 start ecosystem.config.js
之后每次更新文件都会自动重启服务了
踩坑 #
-
actions 里面的三方工具尽量用最新版本
-
执行到 deploy 时
-
permission denied 显示未登录
解决办法:增加 -avzr —delete 参数
-
permission denied 显示没有权限操作
解决办法:查看服务器上面放置文件的文件夹的权限,一般像/var/www/html 是 root 创建的,当前用户没有写的权限,建议将部署路径放置在/home 中,如/home/frontend/projectname
-