返回

Github Action CICD 自动部署

该文章的 Shell 脚本部分过于冗余,若需要看更简约更直观的,可查看 Github Action 实现 CI CD 自动化部署

使用 Github Action 的原因是,jenkins 占用的服务器资源较多,低配置服务器 jenkins 很容易资源打满。

Table of contents

Open Table of contents

了解 Github Action

什么是 GitHub Action?其实也很容易理解,如果你用过 github pages 或者 vercel 的话就不陌生,就是一个 CI/CD 服务。提交代码自动触发部署。那么如何让 github action 连接远程服务器触发部署呢?

网上大部分的教程都是基于 ssh + docker 部署的,说实在,目前有点玩不转 docker,所以已有的思路是:

其实脚本构建这一步和 Dockerfile 是一样的思路。

SSH 连接服务器

GitHub 需要的配置

使用 ssh 连接 服务器,需要 ssh 私钥,但是私钥不能直接写入配置文件,GitHub 提供了相关功能,可以理解为 env

点击项目仓库的 Settings -> Secrets and variables -> Actions -> new repository secret,填入 key 和 value,多个 secret 需要多次创建,在 GitHub Action 中访问时以 object 对象格式访问。跟 js 的对象语法类似。key 就是对象 key,value 就是 对应的值。

secret key 设置

比如 new repository secret 时添加了 key SSH_PRIVATE_KEY,那么在 GitHub Action 中访问时,就使用 ${{ secrets.SSH_PRIVATE_KEY }}

生成 SSH

ssh 公私钥在 ~/.ssh 下,可以 cd 到该目录下 ls 查看。

如果只有一个 authorized_keys,则需要使用 ssh-keygen 生成公私钥对。具体步骤如下

编写 Github Action

此处提供一个 nest 服务的 GitHub Action 示例:

在 项目根目录新建 .github/workflows/deploy.yml 文件,内容如下

name: Deploy-nest

on:
  push:
    branches:
      - server

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: ssh connect server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST }} # ip address
          username: ${{ secrets.SSH_USER }} # server username
          key: ${{ secrets.SSH_PRIVATE_KEY }} # server ssh private key

      - name: Run Script to Deploy serve
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SSH_HOST: ${{ secrets.SSH_HOST }}
          SSH_USER: ${{ secrets.SSH_USER }}
          SERVER_PATH_REMOTE: ${{ secrets.SERVER_PATH_REMOTE }}
          APP_NAME: nest-oss
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan $SSH_HOST >> ~/.ssh/known_hosts
          ssh $SSH_USER@$SSH_HOST  << EOF
            cd $SERVER_PATH_REMOTE

            MAX_RETRIES=8
            RETRY_COUNT=0

            while [ \$RETRY_COUNT -lt \$MAX_RETRIES ]; do
              if git pull origin server; then
                break  # pull succesful exit
              else
                echo "Git pull failed, retrying (\$((RETRY_COUNT + 1)) of \$MAX_RETRIES)..."
                ((RETRY_COUNT++))
                sleep 5
              fi
            done

            # check if retry count exceeded
            if [ \$RETRY_COUNT -eq \$MAX_RETRIES ]; then
              echo "Failed to pull code after \$MAX_RETRIES attempts. Exiting."
              exit 1  # throw error
            fi
            npm install
            npm run build
            pm2 restart $APP_NAME || pm2 start dist/src/main.js --name $APP_NAME
          EOF

最重要的就是 Deploy to server 这个阶段的脚本。简单来说就是连接远程服务器,进入项目目录,执行安装运行脚本,其实就跟正常开发使用命令差不多了,值得注意的是 git pull 阶段增加了错误重试机制,因为国内服务器直接拉取 GitHub 代码失败率较高。

服务器配置

安装 git node pm2

由于有 node 服务,所以需要 node 和 pm2 来管理,如果项目为 java 或者其它,也是同理配置好环境即可。

  1. 安装 git

如果无法连接 github,可在 /etc/hosts 添加如下代码

52.69.186.44 github.com
151.101.64.133 raw.githubusercontent.com
  1. 安装 node
  1. 安装 pm2

这种实现方式是通过拉取仓库代码,运行打包脚本,从而达到部署的,因此,安装时的大量 node_modules 也会占用大量的空间存储,如果介意此种方式,且项目的运行不需要依托 node,例如前端项目,就可以仅上传 dist 目录即可。

简单运行和停止删除命令如下

命令示例

提交代码

此时提交代码就可以触发 GitHub Action 了。失败的话会有邮箱提示,详细信息可以查看 Action 控制台日志。

cicd 成功示例

SSL 证书

证书相关请查看 免费无限续期 SSL 证书



上一篇
从零到一构建并打包 React + TypeScript + Less组件库系列(一、项目初始化搭建+代码规范集成)
下一篇
免费无限续期 SSL 证书