通用CI/CD搭建秘籍:GitHub Action + 阿里云ACR,轻松实现项目自动化部署

在软件开发的快车道上,如何快速、高效地搭建CI/CD流水线,已成为众多开发者追求的目标。本文将为您揭秘一种通用的方法,借助GitHub Action的强大自动化能力和阿里云容器镜像服务(ACR)的稳定支持,轻松实现各类项目的自动化构建与部署。无论是Sz-Admin这样的开源项目,还是您手头的其他项目,只需对提供的脚本进行简单改造,即可快速投入使用,大幅提升开发与运维效率。

Sz-Admin项目作为这一方法的实践案例,成功实现了项目构建和部署流程的自动化与简化。通过GitHub Actions,sz-admin在面对复杂网络环境时,能够有效优化网络资源使用,解决Docker和Maven下载速度慢或不稳定的问题,让部署过程更加流畅。这一方法不仅适用于sz-admin,其通用性和灵活性使其能够轻松适配其他项目,为开发者提供了一种高效、可靠的CI/CD解决方案。

适应场景

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

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

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

前提条件

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

准备阶段

容器镜像服务设置

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

1. 实例创建

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

在这里插入图片描述

2. 访问凭证配置

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

在这里插入图片描述

3. 命名空间创建

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

在这里插入图片描述

4.镜像仓库设置

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

在这里插入图片描述

在这里插入图片描述

5. 查看仓库信息

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

在这里插入图片描述

GitHub机密信息配置

1.访问仓库设置

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

在这里插入图片描述

2. 进入Actions设置

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

在这里插入图片描述

3. 设置仓库机密

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

在这里插入图片描述

在这里插入图片描述

Actions

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

创建 GitHub Actions 工作流

步骤 1: 访问 Actions 页面

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

在这里插入图片描述

步骤 2: 创建新工作流

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

在这里插入图片描述

步骤 3: 配置工作流

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

在这里插入图片描述

步骤 4: 提交工作流文件

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

Workflow

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

Docker Sz-Boot CI 工作流

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

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

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

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

在这里插入图片描述

工作流脚本

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

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  // [!code highlight] // [!code focus] # 服务名称   
      SERVICE_PORT: 9991 # 服务运行的端口号  // [!code focus] // [!code warning]
      RUNNING_ACTIVE: preview # Spring Boot 的运行环境 // [!code highlight] // [!code focus] 
      LOG_DIR: /home/app/sz-service-admin/logs # 日志文件路径 // [!code highlight] // [!code focus] 
      CONFIG_DIR: /home/conf/sz-service-admin # 配置文件路径 // [!code highlight] // [!code focus] 
      ACR_DOMAIN: registry.cn-beijing.aliyuncs.com # Docker 镜像仓库域名(ACR 容器镜像服务域名) // [!code highlight] // [!code focus] 
      ACR_ZONE: sz-action # Docker 镜像的命名空间 // [!code highlight] // [!code focus] 
      VERSION: latest # Docker 镜像的版本 // [!code highlight] // [!code focus] 
      SHELL_RUN_DIR: /home/run # 运行脚本生成路径 // [!code highlight] // [!code focus] 
​
    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 # 执行生成的启动脚本
构建过程一览

在这里插入图片描述

在这里插入图片描述

Docker Sz-Admin CI 工作流

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

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

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

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

在这里插入图片描述

在这里插入图片描述

工作流脚本

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

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  // [!code highlight] // [!code focus] # 服务名称
      RUNNING_ACTIVE: preview  // [!code highlight] // [!code focus] # 运行环境变量
      SERVICE_PORT: 9800  // [!code warning] // [!code focus] # 服务运行的端口号,与 Dockerfile 中的 EXPOSE 属性一致
      NGINX_CONF_DIR: /home/conf/sz-admin-nginx/conf.d  // [!code highlight] // [!code focus] # 远程服务器的 Nginx 配置文件路径
      ACR_DOMAIN: registry.cn-beijing.aliyuncs.com  // [!code highlight] // [!code focus] # Docker 镜像仓库域名
      ACR_ZONE: sz-action  // [!code highlight] // [!code focus] # Docker 镜像命名空间
      VERSION: latest  // [!code highlight] // [!code focus] # 镜像版本
      SHELL_RUN_DIR: /home/run  // [!code highlight] // [!code focus] # 远程服务器脚本存储目录
      VITE_PREVIEW: true  // [!code highlight] // [!code focus] # 是否启用预览模式,控制前端特定功能。仅在预览环境设置为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 # 执行生成的启动脚本
​
构建过程一览

在这里插入图片描述

在这里插入图片描述

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命令启动服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

升职哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值