使用Github-Action持续部署Springboot或vue
案例一
GitHub Actions 是 GitHub 提供的一项持续集成 (CI) 和持续部署 (CD) 服务。它允许你在代码仓库中定义和运行自动化的工作流程,以响应存储库中的事件或调度。GitHub Actions 可以用于构建、测试、打包和部署项目,也可以执行其他自动化任务。
第一步需要先配置 secrets,保证我们的服务器信息不暴露
GitHub Actions 中的 secrets 和 variables 都是用于存储和访问敏感信息或配置的机制
因为我的服务器用的宝塔面板环境,加上构建出来的包和文件并不是很大,所以使用的方式是先在 github action 的环境构建打包,然后将包发送到目标服务器。你也可以在 github action 里让目标服务器执行命令去做 git,构建,部署,启动等等相关的
Springboot
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| name: Java CI with Maven
on: push: branches: [ "master" ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: maven - name: Build with Maven run: mvn -B package --file pom.xml
- name: copy jar uses: cross-the-world/ssh-scp-ssh-pipelines@latest with: host: ${{ secrets.HOST }} user: ${{ secrets.USERNAME }} pass: ${{ secrets.PASSWORD }} port: 22 scp: | ./target/springboot.jar => /home/ last_ssh: | JAR_; PID=$(ps aux | grep "$JAR_NAME" | grep -v grep | awk '{print $2}'); if [ -n "$PID" ]; then kill -9 $PID && echo "进程 $PID 已被杀死"; else echo "未找到与 $JAR_NAME 相关的进程"; fi /usr/bin/java -jar -Xmx1024M -Xms256M /home/springboot.jar &
|
Vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| name: Deploy to Server on: push: branches: [ "master" ] jobs: deploy: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16
- name: Install dependencies run: yarn
- name: Build project run: yarn generate - name: zip dist run: zip -r dist.zip dist/
# 部署到服务器 - name: Deploy 🚀 uses: cross-the-world/ssh-scp-ssh-pipelines@latest with: host: ${{ secrets.HOST }} user: ${{ secrets.USERNAME }} pass: ${{ secrets.PASSWORD }} port: 22 scp: | './dist.zip' => /home last_ssh: | cd /home/ rm -rf dist/ || true unzip dist.zip
|
常见的 GitHub Actions YAML 语法和关键概念
GitHub Actions 使用 YAML 文件来定义工作流程。以下是一些常见的 GitHub Actions YAML 语法和关键概念:
工作流程(Workflow)的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13
| name: My Workflow on: push: branches: - main jobs: my_job: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v2 # 其他步骤...
|
-
name
: 工作流程的名称。
-
on
: 触发工作流程的事件,例如 push
到特定分支。
-
jobs
: 包含一个或多个任务的部分。
任务(Job)的定义:
1 2 3 4 5 6 7
| my_job: runs-on: ubuntu-latest steps: - name: Step 1 run: echo "Hello, World!" # 其他步骤...
|
-
runs-on
: 指定任务运行的操作系统和环境。
-
steps
: 包含一个或多个步骤的列表。
步骤(Steps)的定义:
1 2 3 4 5 6 7 8 9
| steps: - name: Step 1 run: echo "Hello, World!" - name: Step 2 uses: actions/setup-node@v3 with: node-version: '14' # 其他步骤...
|
-
name
: 步骤的名称。
-
run
: 执行的命令或脚本。
-
uses
: 使用的动作(可以是内置动作或自定义动作)。
-
with
: 传递给动作的参数。
触发器(Trigger)的定义:
1 2 3 4 5 6 7 8
| on: push: branches: - main pull_request: branches: - feature/*
|
-
on
: 触发工作流程的事件。
-
push
: 代码推送事件。
-
pull_request
: 合并请求事件。
环境变量(Environment Variables)的定义:
1 2 3 4 5 6 7 8
| jobs: my_job: runs-on: ubuntu-latest env: MY_VARIABLE: my_value steps: # 步骤...
|
Secrets 和 Variables
使用 Secrets:
GitHub Actions 的 secrets 是用于存储敏感信息,例如 API 密钥、访问令牌等。这些 secrets 可以被工作流程中的步骤引用,但它们是加密的,并且只有在运行工作流程时才会暴露给步骤。
- 在 GitHub 存储库中创建 secret:
- 转到 GitHub 存储库的页面。
- 在存储库顶部导航栏中,点击 “Settings”。
- 在左侧边栏中,选择 “Secrets”。
- 点击 “New repository secret”,然后输入 secret 名称和值。
- 在工作流程中使用 secret:
1 2 3 4 5 6 7
| jobs: my_job: runs-on: ubuntu-latest steps: - name: Use secret run: echo ${{ secrets.MY_SECRET }}
|
这里 MY_SECRET
是你创建的 secret 的名称,可以在步骤中使用 ${{ secrets.MY_SECRET }}
引用它。
使用 Variables:
GitHub Actions 的 variables 是由 GitHub 提供的一组默认环境变量,同时你也可以定义自己的环境变量。这些变量可以在工作流程的任何步骤中使用。
- 在工作流程中使用 GitHub 提供的 variables:
1 2 3 4 5 6 7
| jobs: my_job: runs-on: ubuntu-latest steps: - name: Use GitHub-provided variable run: echo ${{ github.event_name }}
|
这里的 github.event_name
是 GitHub 提供的一个默认变量,表示触发工作流程的事件的名称。
- 在工作流程中定义自己的 variables:
1 2 3 4 5 6 7 8 9
| jobs: my_job: runs-on: ubuntu-latest env: MY_VARIABLE: my_value steps: - name: Use custom variable run: echo $MY_VARIABLE
|
在 env
部分定义自己的环境变量,然后在步骤中使用 $MY_VARIABLE
引用它。
注意:GitHub Actions 中的环境变量(包括 secrets 和 variables)在步骤中的引用方式使用 ${{ ... }}
语法。此外,secrets 只能在工作流程的同一存储库中使用,而 variables 则可以在不同存储库的工作流程中共享。
案例二
传统的部署方式是更新代码 -> 本地构建 -> 上传服务器发布;而现代化的部署方式是 CI/CD(持续集成 / 持续部署)
CI/CD 服务有很多:
- Jenkins
- Gitlab CI
- Github Actions
- Travis CI
- Circle CI
- …
开始前需要准备 Linux 服务器;把本地代码提交 GitHub 远程仓库。
然后生成配置 GitHub Actions Token
- 生成 Token:https://github.com/settings/tokens
- 或者可以点击,头像 -> Settings -> Developer settings -> Personal access tokens -> Generate new Token
- Token 名称填写
Token
,Select scopes
勾选 repo,然后滚动到网页最下面点击提交按钮。生成了 Token,复制保存(该 Token 只显示一次,忘记了就再生成)
- 配置到项目的 Secrets 中:进入项目 -> Settings -> Secrets -> New secret
- Name:建议和刚才生成 Token 保持一致
- Value:为刚才生成的 Token
除了配置 Token,还要配置服务器的 HOST、USERNAME、PASSWORD、PORT,这些配置在 GitHub 把项目部署到服务器的时候使用到
这里 GitHun 的配置已经完成,接下要配置 GitHub Actions 执行脚本
- 在项目根目录创建
.githun/workflows
目录
- 在
workflows
目录创建main.yml
文件,文件内容如下,这是 GitHub Actions 执行识别的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| name: Publish And Deploy Demo # 自动部署的名称 on: push: tags: # 当我们提交代码为tag 是以'v'开头的时候才会触发自动部署到服务端 如 git push tag v0.1.0 - 'v*'
jobs: build-and-deploy: runs-on: ubuntu-latest # 运行环境,告诉它运行在什么环境 steps: # 步骤
# 第一步:下载源码(CI/CD拉取代码到自己的本地) - name: Checkout uses: actions/checkout@master
# 第二步:打包构建 - name: Build uses: actions/setup-node@master - run: npm install # 安装第三方包 - run: npm run build # 打包 - run: tar -zcvf release.tgz .nuxt static nuxt.config.js package.json package-lock.json pm2.config.json # 把.nuxt、nuxt.config.js等文件,打包压缩为release.tgz
# 第三步:发布 Release - name: Create Release # 创建Release,可以在仓库看到一个个版本 id: create_release uses: actions/create-release@master env: GITHUB_TOKEN: ${{ secrets.TOKEN }} # 之前GitHub添加的Token with: tag_name: ${{ github.ref }} # (tag)标签名称 release_name: Release ${{ github.ref }} draft: false # 是否是草稿 prerelease: false # 是否是预发布
# 第四步:上传构建结果到 Release(把打包的tgz上传到Release) - name: Upload Release Asset id: upload-release-asset uses: actions/upload-release-asset@master env: GITHUB_TOKEN: ${{ secrets.TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} # 上传地址,通过创建Release获取到的 asset_path: ./release.tgz # 要上传文件 asset_name: release.tgz # 上传后的文件名 asset_content_type: application/x-tgz
# 第五步:部署到服务器 - name: Deploy uses: appleboy/ssh-action@master # 使用ssh链接服务器 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} password: ${{ secrets.PASSWORD }} port: ${{ secrets.PORT }} script: | # 执行命令(运行到服务器)cd:要确保服务器有这个目录; wget:下载上一步的release到服务器; tar:解压; 安装依赖;启动服务 cd /root/realworld-nuxtjs wget https://github.com/YuYun95/realworld-nuxtjs/releases/latest/download/release.tgz -O release.tgz tar zxvf release.tgz npm install --production pm2 reload pm2.config.json
|
到此全部配置已经完成,把代码提交 GitHub 仓库
-
git add .
-
git commit -m "feat: 第一次发布部署"
-
git push
(此时只是推送了提交记录,并不会触发自动化构建部署)
-
git add .
-
git tag v0.1.0
(通过 tag 打版)
-
git tag
(查看版本)
git push origin v0.1.0
(把本地标签推送到远程仓库,会触发自动构建部署)
执行完上面的命令 GitHub Actions 将自动打包部署到服务器
可以点击项目仓库的 Actions 可以查看打包部署过程和结果,全部勾绿色为部署成功,浏览器输入服务器地址即可打开
案例三
一、Github Actions 是什么?
GitHub Actions 是 GitHub 提供的一项功能,用于自动化软件开发工作流程。它允许你在代码仓库中配置和运行自动化任务,以响应各种事件和操作。这些任务可以包括构建、测试、部署和其他 CI/CD(持续集成 / 持续部署)工作流程。
GitHub Actions 的核心概念是工作流程(Workflow)。工作流程是一系列由 GitHub Actions 执行的任务,这些任务根据预定义的触发器(例如推送代码、创建 Pull Request 等)自动触发执行。
GitHub Actions 可以用于自动化执行各种软件开发任务:
- 构建和测试代码。
- 部署应用程序到云服务或服务器。
- 自动化代码审查和测试覆盖率检查。
- 触发持续集成和持续部署流程。
二、Github 项目配置
按照截图的目录配置 SEVER_IP 和 SERVER_PASSWORD。
项目代码中,新建目录. github/workflows,其中新增文件 git-release.yml,目录和内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| name: Git Release CI
# 指定在哪个分支,以及什么操作触发 on: # 在 push 到 master 和 release/1.8.0 的时候触发 push: branches: [ "master", "release/1.8.0" ] # 在对 master 分支实施 pull_request(Merge 其他分支到 master)时触发 pull_request: branches: [ "master" ] # 具体任务配置 jobs:
build: # 指定运行环境 runs-on: ubuntu-latest # 具体的步骤 steps: # checkout 代码到 Github Actions 运行容器中 - uses: actions/checkout@v3 # 获取当前时间,后边打包用 - name: Get Current Date id: date run: echo "::set-output # 向容器安装 Java 21,为 SpringBoot 提供运行环境 - name: Set up JDK 21 uses: actions/setup-java@v3 with: java-version: '21' distribution: 'adopt' # 获取 relase 分支,用于打包 - name: Get Branch Name id: get_branch_name run: echo "::set-output name=branch_name::$(echo $line | grep 'SNAPSHOT' pom.xml | awk '{split($0,a,"-"); print a[1]}'| awk '{split($0,a,">"); print a[2]}')" # 通过 maven 打包 - name: Build with Maven run: mvn -B package --file pom.xml # 向 github 创建 tag 以及 release - name: Create Release id: create_release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ steps.get_branch_name.outputs.branch_name }}-${{ steps.date.outputs.date }} release_name: Release ${{ steps.get_branch_name.outputs.branch_name }}-${{ steps.date.outputs.date }} draft: false prerelease: false # 向 Github 的 Release 上传 jar 包 - name: Upload Release Asset Jar id: upload-release-asset-jar uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: target/stock-and-fund-${{ steps.get_branch_name.outputs.branch_name }}-SNAPSHOT.jar asset_name: stock-and-fund-${{ steps.get_branch_name.outputs.branch_name }}-SNAPSHOT.jar asset_content_type: application/gzip # 向 Github 的 Release 上传 database 文件,如果你的项目没有可以删除这部分 - name: Upload Release Asset DB id: upload-release-asset-db uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: stock-and-fund.db asset_name: stock-and-fund.db asset_content_type: application/gzip # 把 jar 包上传到指定服务器,其中的 secrets.SERVER_IP,secrets.SERVER_PASSWORD 需要在该项目 Github 的 Setting 中配置 - name: copy file to server uses: appleboy/scp-action@v0.1.4 with: host: ${{ secrets.SERVER_IP }} username: root password: ${{ secrets.SERVER_PASSWORD }} port: 22 source: 'target/stock-and-fund-${{ steps.get_branch_name.outputs.branch_name }}-SNAPSHOT.jar' target: '/opt/stock-and-fund/' # ssh 到指定服务器,执行部署命令,具体 deployment.sh 的代码可以去看我之前写的 docker 部署 - name: Deploy stock and fund uses: garygrossgarten/github-action-ssh@release with: command: | cd /opt/stock-and-fund/ rm -rf ./stock-and-fund-${{ steps.get_branch_name.outputs.branch_name }}-SNAPSHOT.jar mv target/stock-and-fund-${{ steps.get_branch_name.outputs.branch_name }}-SNAPSHOT.jar ./ ./deployment.sh host: ${{ secrets.SERVER_IP }} username: root port: 22 password: ${{ secrets.SERVER_PASSWORD }}
|
案例四
一、自动化部署
1.1 提交代码到 Github
1.2 设置服务器密钥、GitHub 私钥、DockerHub 账号
secret | value | remark |
---|
DOCKER_HUB_ACCESS_TOKEN | 1234567890 | dockerhub 账号私钥 |
DOCKER_HUB_USERNAME | bubaiwantong | dockerhub 账号 |
SERVER_HOST | 127.0.0.1 | 服务器 IP 地址 |
SERVER_PASSWORD | 1234567890 | 服务器密码 |
SERVER_PORT | 22 | 服务器开放端口 |
SERVER_PRIVATE_KEY | 1234567890 | 服务器私钥 |
SERVER_USERNAME | root | 服务器账号 |
TOKEN | 1234567890 | Github 的 Token |
1.2.1 设置服务器密钥
1.2.2 设置 Github 私钥
1.2.3 设置 DockerHub 账号
1.3 新增工作流文件
maven.yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| name: Deploy with docker
on: push: # 分支 branches: [ "master" ] pull_request: branches: [ "master" ]
jobs: compile: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up JDK 21 uses: actions/setup-java@v2 with: java-version: '21' distribution: 'adopt' # maven缓存,不加的话每次都会去重新拉取,会影响速度 - name: Dependies Cache uses: actions/cache@v2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- # 编译打包 - name: Build with Maven run: | mvn package -Dmaven.test.skip=true # 登录Docker Hub - name: Login to Docker Hub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v1 #build镜像并push到中央仓库中 - name: Build and push id: docker_build uses: docker/build-push-action@v2 with: context: ./ file: ./Dockerfile push: true tags: ${{secrets.DOCKER_HUB_USERNAME}}/back:latest #push后,用ssh连接服务器执行脚本 - name: SSH # uses: fifsky/ssh-action@master uses: appleboy/ssh-action@master with: # command: | # cd /develop/work/education-back-server # sh start.sh host: ${{secrets.SERVER_HOST}} username: ${{secrets.SERVER_USERNAME}} port: ${{secrets.SERVER_PORT }} # key: ${{secrets.SERVER_PRIVATE_KEY}} password: ${{secrets.SERVER_PASSWORD}} script: sh /develop/work/education-back-server/start.sh # sh start.sh
|
1.4 新增 Dockerfile 文件
Dockerfile文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #基础镜像 FROM bubaiwantong/openjdk:21-jdk-alpine
#安装字体 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/* && mkfontscale && mkfontdir && fc-cache RUN apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/*
#添加文件 ADD education-back/target/back-0.0.1-SNAPSHOT.jar /usr/local RUN chmod u+x /usr/local/back-0.0.1-SNAPSHOT.jar
#设置时区 RUN rm -f /etc/localtime \ && ln -sv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone
#挂载目录到容器 #VOLUME ["/data"] #环境变量设置 #ENV #开放端口 EXPOSE 8088 #启动时执行的命令 CMD ["/bin/bash"] #启动时执行的命令 ENTRYPOINT ["java","-jar","/usr/local/back-0.0.1-SNAPSHOT.jar"]
|
1.5 编写服务器启动脚本
start.sh文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| #!/bin/bash docker pull bubaiwantong/back:latest
docker tag docker.io/bubaiwantong/back:latest back:latest
docker stop back
docker rm back
docker run --name back -p 8088:8088 -d back:latest
docker image prune -
|
2.7 开启自动化部署
提交代码到 master,在 GitHub 中的 Actions 即可发现项目正在自动化部署
在浏览器地址栏打开[ 就可以发现自动化部署成功啦!