持续集成指南:GitHubAction 自动构建+部署AspNetCore项目

news2024/11/29 22:45:17

前言

之前研究了使用 GitHub Action 自动构建和发布 nuget 包:开发现代化的.NetCore控制台程序:(4)使用GithubAction自动构建以及发布nuget包

现在更进一步,使用 GitHub Action 在其提供的 runner 里构建 docker 镜像,之后提交到阿里云镜像私有仓库,再在本地的 runner 将镜像 pull 下来运行。

本文以 AIHub 项目为例。

AIHub 是一个集成多种模型的AI平台,提供了大模型、计算机视觉、自然语言处理等多种功能,基于 AspNetCore + Blazor Server 技术开发。

准备 Dockerfile

首先准备好构建镜像的 Dockerfile

一般来说使用 dotnet cli 创建项目的时候可以自动生成这个 Dockerfile

没有的话可以参考我这个

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["AIHub.Blazor/AIHub.Blazor.csproj", "AIHub.Blazor/"]
RUN dotnet restore "AIHub.Blazor/AIHub.Blazor.csproj"
COPY . .
WORKDIR "/src/AIHub.Blazor"
RUN dotnet build "AIHub.Blazor.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "AIHub.Blazor.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AIHub.Blazor.dll"]

可以先在本地试一下 build 有没有问题

docker build .

一切正常可以进入下一步

创建私有镜像仓库

可以自行搭建,也可以使用云服务产品,我这里使用阿里云的「容器镜像服务 ACR」,个人版是免费的。

创建一个镜像仓库,代码源选择「本地仓库」,可以通过命令行推送镜像到镜像仓库。

PS: 我看里面还有 GitHub 仓库作为代码源,不过我还没测试。

创建之后有个操作指南,这不是很重要,我们只需要关注用户名和密码就行。

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

可以在访问凭证页面修改凭证密码。

OK,这些信息保存好,接下来需要用到。

本文使用的仓库地址是: registry.cn-hangzhou.aliyuncs.com/deali/aihub-test

配置 GitHub Action Secret

将阿里云仓库的地址、用户名、密码等信息配置到 Action Secret 中

这里我设置的名字是

  • ALIYUN_DOCKER_REPO

  • ALIYUN_USERNAME

  • ALIYUN_PWD

构建镜像

编写 GitHub workflow 配置,细节不再赘述,不清楚的同学可以参考这篇文章: 开发现代化的.NetCore控制台程序:(4)使用GithubAction自动构建以及发布nuget包

GitHub 提供的 workflow

这是 GitHub 提供的,我没有使用这个方案,有兴趣的同学可以自行尝试一下。

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。

# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。

name: Publish Docker image

on:
  release:
    types: [published]

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repo
        uses: actions/checkout@v4
      
      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: my-docker-hub-namespace/my-docker-hub-repository
      
      - name: Build and push Docker image
        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

简单版 workflow

这是我自己写的 workflow 比 GitHub 提供的例子简单一些

name: Docker Image CI
run-name: ${{ github.actor }} is building a image

on: [push]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Build the Docker image
      run: docker build . --file ./next-antd/AIHub.Blazor/Dockerfile --tag ${{ secrets.ALIYUN_DOCKER_REPO }}:${{ github.run_id }}
    - name: Login to aliyun docker repository
      run: docker login -u ${{ secrets.ALIYUN_USERNAME }} -p ${{ secrets.ALIYUN_PWD }} ${{ secrets.ALIYUN_DOCKER_REPO }}
    - name: Push image to aliyun docker repository
      run: docker push ${{ secrets.ALIYUN_DOCKER_REPO }}:${{ github.run_id }}

这个 build 步骤,在 GitHub 托管的 runner 上构建 docker 镜像,并且推送到私有镜像仓库。

镜像的 tag 版本,我使用了 run_id 这个环境变量,代表本次构建任务的唯一ID,例如 1658821493

也可以使用 ${{ github.sha }} 代表这次的 commit sha ,但我觉得太长了就没有使用

GITHUB_SHA: 触发工作流的提交 SHA。 此提交 SHA 的值取决于触发工作流程的事件。 有关详细信息,请参阅“触发工作流的事件”。 例如,ffac537e6cbbf934b08745a378932722df287a53

PS:官方提供的例子使用的是 $(date +%s) 时间戳,但我还没探索出在环境变量里拼接字符串的方法。

搭建本地 runner

镜像构建完事了,还得在本地的服务器上跑。

很简单,就是把镜像 pull 下来,然后 docker compose up 就行,现在我们把这一步也加入到 workflow 里。

添加 runner

访问这个页面: https://github.com/star-plan/aihub/settings/actions/runners

点击 New self-hosted runner 按钮

选择对应的系统和架构,然后根据里面的命令来就完事了。

本文选择的是 Linux - x64 的方案

GitHub 提供的命令是这样(这里只是给出例子,实际要以自己的项目配置页面为准)

# Create a folder
$ mkdir actions-runner && cd actions-runner# Download the latest runner package
$ curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz# Optional: Validate the hash

其中下载这一步可能会遇到问题,因为某些莫名其妙的原因,GitHub 访问不了,这时候需要使用 proxychains 工具,请自行搜索 + 配置。

PS:好家伙,这个 runner 居然有 180M

接着运行命令 runner

./config.sh --url [REPO_URL] --token [TOKEN]

  • 提示输入 runner group 名称,默认即可

  • 提示需要输入 runner 名字,我输入了个 aihub

  • 接着还可以输入 label 啥的,根据需求来就行

配置搞定之后就启动 runner

./run.sh

安装服务

用 ./run.sh 启动的 runner 并不稳定,退出登录之后就无了,就算使用 & 或者 Ctrl+Z 切换到后台执行,也不是那么稳定。

GitHub runner 可以作为 Linux 服务运行,使用也很简单。

先关掉正在运行的 runner

ps aux | grep run.sh
# 找到 pid 之后 kill 掉
kill -9 pid

安装服务

sudo ./svc.sh install

启动服务

sudo ./svc.sh start

更多操作请查看第四条参考资料。

查看 runner 列表

在 GitHub 页面上查看当前运行的 runner

地址: https://github.com/star-plan/aihub/settings/actions/runners

可以看到已经有一个叫 aihub 的 runner 了

runner 网络代理

这波我只能说 GitHub 太贴心了!他已经考虑到了不能上 GitHub 的情况,他真的,我哭死😭

可以在环境变量里设置代理,也可以在 .env 文件里配置,这里我还是选 .env 吧。

https_proxy=http://proxy.local:8080
no_proxy=example.com,myserver.local:443


更多关于搭建本地 runner 的文档,可以查看参考资料的第三条。

使用本地 runner 部署服务

老规矩,使用 docker-compose 来编排服务。

先创建个目录,里面存放 docker-compose.yml 和一些持久化的文件。

本例子的路径是: /home/apps/aihub

version: '3.6'

services:
  web:
    image: ${IMAGE}
    container_name: aihub-test
    restart: always
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://+:80
    volumes:
      - ./aihub.app.db:/app/aihub.app.db
    ports:
      - "12002:80"
    networks:
      - default
      - swag

networks:
  swag:
    name: swag
    external: true
  default:
    name: aihub-test

镜像部分我用了环境变量,因为每次构建的镜像tag都不一样,我要在 workflow 里将 tag 写入 .env 文件。当然也可以写固定 latest 。

.env 文件是这样

IMAGE=registry.cn-hangzhou.aliyuncs.com/deali/aihub-test:6861065827

OK,总算是到了最后一步,继续编辑我们的 workflow ,增加一个 deployment 任务。

name: Docker Image CI
run-name: ${{ github.actor }} is building a image

on: [push]

jobs:

  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Build the Docker image
      run: docker build . --file ./next-antd/AIHub.Blazor/Dockerfile --tag ${{ secrets.ALIYUN_DOCKER_REPO }}:${{ github.run_id }}
    - name: Login to aliyun docker repository
      run: docker login -u ${{ secrets.ALIYUN_USERNAME }} -p ${{ secrets.ALIYUN_PWD }} ${{ secrets.ALIYUN_DOCKER_REPO }}
    - name: Push image to aliyun docker repository
      run: docker push ${{ secrets.ALIYUN_DOCKER_REPO }}:${{ github.run_id }}

	deployment:
    runs-on: [self-hosted, linux, x64]
    needs: [build]
    steps:
    - name: export environment variant
      run: echo 'IMAGE=${{ secrets.ALIYUN_DOCKER_REPO }}:${{ github.run_id }}' > /home/apps/aihub/.env
    - name: docker compose deploy
      run: docker compose -f /home/apps/aihub/docker-compose.yml --project-directory /home/apps/aihub up -d

注意:

  • jobs 默认是并行执行的,所以需要在 deployment 任务里加上 needs 配置,等 build 完了再部署

  • 使用 jobs.<job_id>.needs 标识运行此作业之前必须成功完成的所有作业。 它可以是一个字符串,也可以是字符串数组。 如果某个作业失败或跳过,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。 如果运行包含一系列相互需要的作业,则故障或跳过将从故障点或跳过点开始,应用于依赖项链中的所有作业。 如果希望某个作业在其依赖的作业未成功时也能运行,请在 jobs.<job_id>.if 中使用 always() 条件表达式。

  • deployment 任务是在本地执行的,所以 runs-on 通过多个 label 选择了本地 runner

  • 执行 docker compose 命令的时候工作目录是在 GitHub Action 工具的 _work 目录里,所以需要指定 --project-directory 参数,或者通过 --env-file 指定 .env 文件位置

查看执行结果

在 GitHub Action 页面可以查看执行结果。

搞定!

参考资料

  • 变量 - GitHub 文档

  • 发布 Docker 映像 - GitHub 文档

  • 关于自托管运行程序 - GitHub 文档

  • 将自托管的运行应用程序配置为服务 - GitHub 文档

  • 将代理服务器与自托管运行程序结合使用 - GitHub 文档

  • 在工作流程中使用作业 - GitHub 文档

  • Ways to set environment variables in Compose | Docker Docs

文章转载自:程序设计实验室

原文链接:https://www.cnblogs.com/deali/p/17833948.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美联储暂停加息 黄金代理要“笑嘻嘻”?

在11月的议息会议上&#xff0c;美联储再次宣布暂停加息。这是继九月份以后&#xff0c;美联储再次做同样的决定&#xff0c;目前已经实现了2连停。停止加息意味着美元资产的吸引度下降&#xff0c;美元指数将会受压&#xff0c;现货黄金价格因为美元的走弱可能上涨&#xff0c…

晨控CK-FR08读卡器与汇川PLC连接EtherCAT通讯手册

晨控CK-FR08读卡器与汇川PLC连接EtherCAT通讯手册 晨控CK-FR08系列是一款基于射频识别技术的高频RFID标签读卡器&#xff0c;读卡器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。 读卡器同时支持标准工业通讯协议Eth…

一文讲透IGBT工作原理 | 百能云芯

在实际应用中最流行和最常见的电子元器件是双极结型晶体管 BJT 和 MOS管。 IGBT实物图电路符号图 你可以把 IGBT 看作 BJT 和 MOS 管的融合体&#xff0c;IGBT具有 BJT 的输入特性和 MOS 管的输出特性。与 BJT 或 MOS管相比&#xff0c;绝缘栅双极型晶体管 IGBT 的优势在于它提…

Linux Control Cgroups

无论 Docker 如何进行隔离&#xff0c;无法否认的是我们在当前宿主机中运行的所有容器&#xff0c;它依赖的硬件资源都只是当前机器。 其实启动的每一个容器进程&#xff0c;它本身其实就是当前宿主机的进程之一&#xff0c;那么本质上来说&#xff0c;它也会和宿主机中的其他…

接口测试自动化测试的总结与思考,超详细的~

服务端接口测试介绍 什么是服务端? 一般所说的服务端是指为用户在 APP 或 PC 使用的互联网功能提供数据服务的背后的一切。以天猫精灵智能音箱系列的产品链路为例&#xff0c;服务端便是网关&#xff08;包括网关在内&#xff09;之后的链路。 什么是接口? 官方点说&#…

国内也可以做伦敦金的吗?给你答案

虽然伦敦金是国际市场上的贵金属投资方式&#xff0c;但国内投资者同样有机会参与其中&#xff0c;最简单的方式就是通过香港的持牌平台&#xff0c;在网上开设一个账号&#xff0c;并往其中注入一定的资金之后&#xff0c;就可以展开交易。 国内投资者可以炒伦敦金&#xff0c…

Unittest框架--自动化

Python中方法的传递 参数化 pip install parameterized -i https://pypi.douban.com/simple需求&#xff1a;验证Tpshop登录 # 断言参数化 import time import unittest from parameterized import parameterized from selenium import webdriver from selenium.webdriver.co…

飞书开发学习笔记(七)-添加机器人及发送webhook消息

飞书开发学习笔记(七)-添加机器人及发送webhook消息 一.添加飞书机器人 1.1 添加飞书机器人过程 在群的右上角点击折叠按键…选择 设置 群机器人中选择 添加机器人 选择自定义机器人&#xff0c;通过webhook发送消息 弹出的信息中有webhook地址&#xff0c;选择复制。 安…

【Mysql】关于数据库增删查改的一些在线OJ练习

&#x1f308;欢迎来到Python专栏 &#x1f64b;&#x1f3fe;‍♀️作者介绍&#xff1a;前PLA队员 目前是一名普通本科大三的软件工程专业学生 &#x1f30f;IP坐标&#xff1a;湖北武汉 &#x1f349; 目前技术栈&#xff1a;C/C、Linux系统编程、计算机网络、数据结构、Mys…

YOLOV5部署Android Studio安卓平台NCNN

坑非常多&#xff0c;兄弟们&#xff0c;我已经踩了三天的坑了&#xff0c;我这里部署了官方的yolov5s和我自己训练的yolov5n的模型 下载Android Studio&#xff0c;配置安卓开发环境&#xff0c;这个过程比较漫长。 安装cmake&#xff0c;注意安装的是cmake3.10版本。 根据手机…

世界上最便宜好用的服务器低至 $9.99 / 年

世界上最便宜好用的服务器低至 $9.99 / 年 是一个非常爱搞促销的商家&#xff0c;目前只有一个洛杉矶 DC 机房&#xff0c;每次促销给的流量很足&#xff0c;下面总结的促销套餐&#xff0c;经过测试竟然完美超过甲骨文 1 核 6G 的机器&#xff0c;不仅仅 io 完胜&#xff0c;而…

svg图标最简单的使用方式

svg图标最简单的使用方式 使用svg图标1. 复制图标的svg代码2. 新建个存放svg图标的目录&#xff0c;新建.vue文件3. 在<template>标签内粘贴svg的代码4. 在代码中也可以调整颜色和大小5. 在组件中引用6. svg做的图标要独占一行,使用布局将它安排到合适的地方 使用svg图标…

【JavaEE初阶】 HTML基础详解

文章目录 &#x1f38b;什么是HTML&#xff1f;&#x1f340;HTML 结构&#x1f6a9;认识标签&#x1f6a9;HTML 文件基本结构&#x1f6a9;快速生成代码框架 &#x1f384;HTML 常见标签&#x1f6a9;注释标签&#x1f6a9;标题标签: h1-h6&#x1f6a9;段落标签: p&#x1f6…

NFG数字藏品:潮流文化与科技的完美结合

​小编介绍&#xff1a;10年专注商业模式设计及软件开发&#xff0c;擅长企业生态商业模式&#xff0c;商业零售会员增长裂变模式策划、商业闭环模式设计及方案落地&#xff1b;扶持10余个电商平台做到营收过千万&#xff0c;数百个平台达到百万会员&#xff0c;欢迎咨询。 数…

[Python学习笔记]Python 性能分析

在上一章节 [Python学习笔记]Requests性能优化之Session 中&#xff0c;通过在 Resquests 中使用 session&#xff0c;将 Python 脚本的运行效率提升了 3 倍。但当时对问题的排查主要是基于程序实现逻辑的推断&#xff0c;并没有实质性的证据。 本次使用 Python 的性能分析工具…

使用docker部署nacos分布式集群

本文目的 在服务器中部署nacos集群&#xff0c;并连接外置数据库关于外置的mysql部署和单例nacos如何部署请看下面的两个链接 如何使用docker部署mysql docker部署容器化mysql5.7-CSDN博客 如何使用docker部署nacos 容器化部署Nacos&#xff1a;从环境准备到启动-CSDN博客…

ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION packages field missing or empty

vue执行 pnpm install命令时&#xff0c;报 ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION  packages field missing or empty错&#xff0c;在网上查询了很久&#xff0c;也没有传出来结果&#xff0c;最后发现是pnpm的版本不对引起的。 我先执行的是npm install -g pnpm&…

T13级专家被毕业?!研发大牛被裁带来的警示丨IDCF

2005年加入腾讯&#xff0c;腾讯第一位Web前端专家&#xff0c;T13职级&#xff0c;今年1月仍是腾讯前端最高专家。 在47岁的时候&#xff0c;拥有这样简历的前端大牛黄希彤被腾讯裁员。 黄希彤夫人在小红书上透露&#xff1a;&#xff08;黄希彤&#xff09;在鹅厂工作了15年…

csapp attack lab phase4

csapp attack lab phase4 每个gadget由一系列指令字节组成&#xff0c;最后一个字节为0xc3&#xff0c;编码为ret指令。 举个例子: 48 89 c7 是指令 movq %rax, %rdi&#xff0c; 对应的地址是0x400f15 0x3 也就是0x400f18, 是开始的指令位置。 例如&#xff1a; ret编码为0…

为防下架,我把虎*牙舞蹈小姐姐视频批量下载啦~

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用: Python 3.10 解释器 Pycharm 编辑器 模块使用: requests >>> 数据请求 第三方模块 pip install requests <工具> win R 输入cmd 输入安装命令…