Skip to content

GitHub Actions

sz-admin 在保留传统部署方式的基础上,积极引入现代化部署策略,以满足不同用户的需求。我们特别支持使用GitHub Actions工作流,这一现代化工具能够显著提升项目的构建和部署效率。通过GitHub Actions,部署流程被极大简化,自动化程度得到提升,从而为您节省了宝贵的时间和资源。

在面对复杂的网络环境时,GitHub Actions的优势尤为明显。它能有效帮助我们优化网络资源的使用,特别是在处理Docker和Maven下载时,能够更加合理地分配和利用网络带宽,解决下载速度慢或不稳定的问题。这种智能化的解决方案,让部署过程更加流畅,提高了整体的开发和运维效率。

适应场景

个人和小团队项目: GitHub Actions非常适合个人开发者和小团队使用,它提供了一个灵活的自动化流程,可以轻松集成到您的项目中。

不稳定网络环境: 对于网络连接不稳定的宿主机环境,GitHub Actions能够提供更为稳定的构建和部署流程。它通过优化Docker、Maven和NPM等工具的下载和构建过程,减少了网络波动对项目进度的影响。

资源受限的服务器: GitHub Actions提供了免费的打包机(runners),这些打包机可以帮助您在云端执行构建和部署任务,从而减轻您本地服务器的资源负担。通过这种方式,您可以在资源受限的环境中,利用GitHub Actions的云端资源来完成项目打包和部署,有效降低对本地服务器资源的占用。

前提条件

项目描述
Docker宿主机必须支持Docker,以便于容器化部署和管理。
网络项目需要能够访问公网,以确保服务的正常运行和外部通信。
容器镜像服务推荐使用阿里云ACR或其他云服务商提供的容器镜像服务作为您的制品库。为了加快镜像下载速度,建议选择与服务器托管服务商同源的镜像服务商。
Github项目的源码应托管在GitHub上,可以是私有仓库或公开仓库,以便于代码管理和协作。

准备阶段

容器镜像服务设置

以阿里云容器镜像服务(ACR)个人版为例,进行以下步骤:

1. 实例创建

访问阿里云ACR控制台,点击创建实例按钮以启动个人版实例。个人版免费且提供的配额足以满足大多数使用场景。

image-20250103104402929

2. 访问凭证配置

通过设置固定密码按钮配置访问凭证。

image-20250103104546141

3. 命名空间创建

个人版提供了三个免费的命名空间。

image-20250103104921187

4.镜像仓库设置

在选定的命名空间中创建镜像仓库,并设置仓库名称及代码源。

image-20250103105145306

image-20250103105200568

5. 查看仓库信息

在仓库列表页,点击仓库名称查看并管理仓库基本信息。

image-20250103105740163

GitHub机密信息配置

1.访问仓库设置

选择您的代码仓库,进入Settings页面。

image-20250103110104185

2. 进入Actions设置

Settings中找到并选择Secrets and variables ,然后点击Actions

image-20250103110148850

3. 设置仓库机密

点击New repository secret创建加密存储的机密变量。

image-20250103110428874

image-20250103110636296

Actions

NOTE

完成上述准备工作后,接下来我们可以创建Actions了。

创建 GitHub Actions 工作流

步骤 1: 访问 Actions 页面

首先,导航到您的代码仓库,并进入 Actions 页面。

image-20250103142507789

步骤 2: 创建新工作流

Actions 页面,点击 New workflow 按钮以开始创建一个新的工作流。

image-20250103142651893

步骤 3: 配置工作流

选择一个模板进行 Configure,这将引导您进入工作流的编辑页面。在此过程中,GitHub 会自动为您创建一个 .github/workflows/xxx.yml 文件。

image-20250103143222047

步骤 4: 提交工作流文件

确认工作流配置无误后,提交该 .yml 文件以完成工作流的创建。您也可以选择使用集成开发环境(IDE)如 IntelliJ IDEA 来创建和编辑 .github/workflows/xxx.yml 文件。

Workflow

NOTE

以下提供的是针对 Sz-Admin 项目的 SpringBoot 和 Vue 应用的 preview 预览环境的 GitHub Actions 工作流配置示例。根据您的具体业务需求和项目结构,您可能需要对这些配置进行适当的调整和优化。

Docker Sz-Boot CI 工作流

WARNING

为确保工作流的顺利执行,请提前在宿主机上准备以下条件:

  1. 目录准备:请确保已在宿主机上创建了必要的目录,并且相关配置文件已经配置妥当。

  2. 敏感信息保护:为了保护生产环境中的敏感信息,Docker Sz-Boot CI 工作流提供了配置挂载功能。该功能允许您将核心配置文件挂载到宿主机上,具体路径由环境变量env.CONFIG_DIR指定。请确保您已经将所有敏感文件上传至该指定目录。

    env.CONFIG_DIR指定的目录内容示例如下:

    image-20250103145943654

工作流脚本

以下是一个针对 Sz-Admin SpringBoot项目的GitHub Actions工作流配置示例。这个工作流将帮助您自动化构建和部署您的SpringBoot应用。

yaml
name: Docker Sz-Boot CI # CI 工作流名称

on: 
  push: # 当代码推送到指定分支时触发工作流
    branches: [ "preview" ] 
  pull_request: # 当向指定分支发起 PR 时触发工作流
    branches: [ "preview" ]
  workflow_dispatch: # 手动触发工作流

jobs:
  build: 
    runs-on: ubuntu-latest # 使用最新版本的 Ubuntu 运行器
    env: # 定义工作流中的环境变量
      APP_NAME: sz-service-admin # 服务名称   
      SERVICE_PORT: 9991 # 服务运行的端口号
      RUNNING_ACTIVE: preview # Spring Boot 的运行环境
      LOG_DIR: /home/app/sz-service-admin/logs # 日志文件路径
      CONFIG_DIR: /home/conf/sz-service-admin # 配置文件路径
      ACR_DOMAIN: registry.cn-beijing.aliyuncs.com # Docker 镜像仓库域名(ACR 容器镜像服务域名)
      ACR_ZONE: sz-action # Docker 镜像的命名空间
      VERSION: latest # Docker 镜像的版本
      SHELL_RUN_DIR: /home/run # 运行脚本生成路径

    steps:
      - name: Checkout code # 拉取代码
        uses: actions/checkout@v4

      - name: Set up JDK 21 # 安装 Java 21 运行环境
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu' # 使用 Zulu JDK
          java-version: '21'

      - name: Set up Maven # 配置 Maven 构建工具
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '21'
          cache: 'maven' # 启用 Maven 缓存以加快构建速度

      - name: Build with Maven # 使用 Maven 构建项目
        run: mvn clean package

      - name: Copy JAR file # 复制构建生成的 JAR 文件
        run: |
          cd ./sz-service/sz-service-admin/target
          cp ./*.jar ../../../app.jar

      - name: Build Docker image # 构建 Docker 镜像
        run: docker build -t ${{ env.APP_NAME }}:${{ env.VERSION }} .

      - name: Log in to Docker ACR # 登录到 Docker 镜像仓库
        run: echo "${{ secrets.ACR_PASSWORD }}" | docker login --username=${{ secrets.ACR_USERNAME }} ${{ env.ACR_DOMAIN }} --password-stdin

      - name: Tag Docker image # 标记 Docker 镜像
        run: docker tag ${{ env.APP_NAME }}:${{ env.VERSION }} ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}

      - name: Push Docker image # 推送 Docker 镜像到仓库
        run: docker push ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}

      - name: Deploy to remote server # 部署到远程服务器
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ secrets.REMOTE_HOST }} # 远程服务器地址
          username: ${{ secrets.REMOTE_USER }} # SSH 用户名
          password: ${{ secrets.REMOTE_PASSWORD }} # SSH 密码
          script: |
            docker pull  ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}
            
            echo "==================== 生成启动命令脚本 ===================="
            mkdir -p ${{ env.SHELL_RUN_DIR }}
            START_SCRIPT="${{ env.SHELL_RUN_DIR }}/docker_run_${{ env.APP_NAME }}_${{ env.RUNNING_ACTIVE }}.sh"
            cat > $START_SCRIPT <<EOL
            #!/bin/bash
              echo "==================== 停止旧应用容器 ===================="
              docker stop ${{ env.APP_NAME }} || true
              docker rm ${{ env.APP_NAME }} || true 
              docker image prune -f
              docker builder prune -f 
              echo "==================== 启动应用容器 ===================="
              docker run -itd \\ # 启动新的容器
              --name ${{ env.APP_NAME }} \\ 
              --restart always \\
              -p ${{ env.SERVICE_PORT }}:${{ env.SERVICE_PORT }} \\ 
              -v ${{ env.LOG_DIR }}:/logs \\
              -v ${{ env.CONFIG_DIR }}:/config \\ 
              -e "SPRING_PROFILES_ACTIVE=${{ env.RUNNING_ACTIVE }}" \\ 
              ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}
            EOL
            chmod +x $START_SCRIPT # 赋予脚本可执行权限
            echo "启动脚本已生成:$START_SCRIPT"
            echo "可以运行以下命令手动启动容器:"
            echo "bash $START_SCRIPT"
            bash $START_SCRIPT # 执行生成的启动脚本
构建过程一览

image-20250103151349432

image-20250103151406057

Docker Sz-Admin CI 工作流

WARNING

为确保工作流的顺利执行,请提前在宿主机上准备以下条件:

  1. 目录准备:请确保已在宿主机上创建了必要的目录,并且相关配置文件已经配置妥当。

  2. Nginx配置映射:对于前端的Nginx配置目录,我们实现了挂载映射功能。您可以通过设置环境变量env.NGINX_CONF_DIR来指定文件映射目录。在首次部署时,系统会自动启用并上传源码目录下的nginx/default.conf配置文件到指定目录作为默认配置。后续部署中,系统会检测该配置文件是否存在,如果存在,则不再使用源码中的配置,而是以修改后的信息为主。

    env.NGINX_CONF_DIR指定的目录内容示例如下:

    ![image-20250103145943654](github-cicd/image-20250103145943654.pngimage-20250103153459065

注意: 在使用默认配置文件之前,请确保您已经调整了default.conf中的API和socket服务地址,以匹配您的服务地址。修改完成后,您需要运行位于env.SHELL_RUN_DIR目录下的相应脚本来使更改生效。

image-20250103154028033

image-20250103154115853

工作流脚本

以下是一个针对 Sz-Admin Vue项目的GitHub Actions工作流配置示例。这个工作流将帮助您自动化构建和部署您的前端应用。

yaml
name: Docker Sz-Admin CI # CI/CD 工作流名称

on: 
  push: # 当推送代码到 "preview" 分支时触发
    branches: [ "preview" ]
  pull_request: # 当有针对 "preview" 分支的 PR 时触发
    branches: [ "preview" ]

jobs:
  build:
    runs-on: ubuntu-latest # 在最新版本的 Ubuntu 运行器上执行
    env: # 定义环境变量
      APP_NAME: sz-admin # 服务名称
      RUNNING_ACTIVE: preview # 运行环境变量
      SERVICE_PORT: 9800 # 服务运行的端口号,与 Dockerfile 中的 EXPOSE 属性一致
      NGINX_CONF_DIR: /home/conf/sz-admin-nginx/conf.d # 远程服务器的 Nginx 配置文件路径
      ACR_DOMAIN: registry.cn-beijing.aliyuncs.com # Docker 镜像仓库域名
      ACR_ZONE: sz-action # Docker 镜像命名空间
      VERSION: latest # 镜像版本
      SHELL_RUN_DIR: /home/run # 远程服务器脚本存储目录
      VITE_PREVIEW: true # 是否启用预览模式,控制前端特定功能。仅在预览环境设置为true。

    steps:
      - name: Checkout repository # 检出代码仓库
        uses: actions/checkout@v4

      - name: Set up Node.js # 配置 Node.js 环境
        uses: actions/setup-node@v4
        with:
          node-version: '20' # 使用 Node.js 20 版本

      - name: Install pnpm # 全局安装 pnpm 包管理器
        run: npm install -g pnpm

      - name: Install dependencies # 安装项目依赖
        run: pnpm install

      - name: Build project # 构建项目
        env:
          VITE_PREVIEW: ${{ env.VITE_PREVIEW }} # 传递预览模式环境变量
        run: pnpm run build

      - name: Install sshpass # 安装 sshpass,用于非交互式 SSH 操作
        run: sudo apt-get update && sudo apt-get install -y sshpass

      - name: Check if default.conf exists on remote # 检查远程服务器上是否存在 default.conf 文件
        id: check-file
        run: |
          file_exists=$(sshpass -p ${{ secrets.REMOTE_PASSWORD }} ssh -o StrictHostKeyChecking=no ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }} "if [ -f ${{ env.NGINX_CONF_DIR }}/default.conf ]; then echo true; else echo false; fi")
          echo "file_exists=$file_exists" >> $GITHUB_ENV

      - name: Upload default.conf if needed # 如果 default.conf 文件不存在,则上传
        if: ${{ env.file_exists == 'false' }}
        run: sshpass -p ${{ secrets.REMOTE_PASSWORD }} scp -o StrictHostKeyChecking=no ./nginx/default.conf ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }}:${{ env.NGINX_CONF_DIR }}

      - name: Build Docker image # 构建 Docker 镜像
        run: docker build -t ${{ env.APP_NAME }}:${{ env.VERSION }} .

      - name: Log in to ACR # 登录到 Docker 镜像仓库
        run: echo "${{ secrets.ACR_PASSWORD }}" | docker login --username=${{ secrets.ACR_USERNAME }} ${{ env.ACR_DOMAIN }} --password-stdin

      - name: Tag Docker image # 给 Docker 镜像打标签
        run: docker tag ${{ env.APP_NAME }}:${{ env.VERSION }} ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}

      - name: Push Docker image to ACR # 推送 Docker 镜像到仓库
        run: docker push ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}

      - name: Deploy to remote server # 部署到远程服务器
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ secrets.REMOTE_HOST }} # 远程服务器地址
          username: ${{ secrets.REMOTE_USER }} # SSH 用户名
          password: ${{ secrets.REMOTE_PASSWORD }} # SSH 密码
          script: |
            docker pull ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}

            echo "==================== 生成启动命令脚本 ===================="
            mkdir -p ${{ env.SHELL_RUN_DIR }}
            START_SCRIPT="${{ env.SHELL_RUN_DIR }}/docker_run_${{ env.APP_NAME }}_${{ env.RUNNING_ACTIVE }}.sh"
            cat > $START_SCRIPT <<EOL
            #!/bin/bash
              echo "==================== 停止旧应用容器 ===================="
              docker stop ${{ env.APP_NAME }} || true 
              docker rm ${{ env.APP_NAME }} || true 
              docker image prune -f 
              docker builder prune -f 
              echo "==================== 启动应用容器 ===================="
              docker run -itd \\ 
              --name ${{ env.APP_NAME }} \\ 
              --restart always \\ 
              -p ${{ env.SERVICE_PORT }}:${{ env.SERVICE_PORT }} \\ 
              -e TZ=Asia/Shanghai \\ 
              -v ${{ env.NGINX_CONF_DIR }}:/etc/nginx/conf.d \\ 
              ${{ env.ACR_DOMAIN }}/${{ env.ACR_ZONE }}/${{ env.APP_NAME }}:${{ env.VERSION }}
            EOL
            chmod +x $START_SCRIPT # 赋予脚本执行权限
            echo "启动脚本已生成:$START_SCRIPT"
            echo "可以运行以下命令手动启动容器:"
            echo "bash $START_SCRIPT"
            bash $START_SCRIPT # 执行生成的启动脚本
构建过程一览

image-20250103152041751

image-20250103152153474

Sz CI 机密变量设置

以下是Docker Sz-Boot CIDocker Sz-Admin CI需要创建的变量。请根据您的实际情况进行配置:

ProjectNameDetail
Docker Sz-Boot CI && Docker Sz-Admin CIACR_USERNAME容器镜像服务-用户名
Docker Sz-Boot CI && Docker Sz-Admin CIACR_PASSWORD容器镜像服务-访问密码(私有)
Docker Sz-Boot CI && Docker Sz-Admin CIREMOTE_HOST宿主机(SSH) IP
Docker Sz-Boot CI && Docker Sz-Admin CIREMOTE_USER宿主机(SSH)账户
Docker Sz-Boot CI && Docker Sz-Admin CIREMOTE_PASSWORD宿主机(SSH)密码

请确保您已正确设置这些机密变量,以便GitHub Actions能够安全地访问和部署您的项目。

发布流程

以sz-boot-parent 为例,简述发布流程如下:

  1. 代码提交:首先,将代码提交至GitHub的指定分支。
  2. 自动化触发:提交后,自动触发CI/CD Workflow流程。
  3. 代码克隆:在Runner虚拟机环境中,克隆项目代码。
  4. 环境准备:
    • 下载并安装JDK环境。
    • 下载并配置Maven工具。
  5. 构建项目:使用Maven进行项目打包。
  6. Docker镜像构建:构建Docker镜像。
  7. 镜像存储:将构建好的Docker镜像上传至ACR(阿里云)制品库。
  8. 远程连接:通过SSH连接到宿主机。
  9. 镜像下载与部署:
    • 从ACR制品库下载所需的制品镜像。
    • 使用docker run命令启动服务。