二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • 最佳实践

  • 迎刃而解

  • Nginx

  • Php

  • Zabbix

  • AWS

  • Prometheus

  • Grafana

  • Loki

  • CentOS

  • Supervisord

  • Systemd

  • Docker

  • Docker-Compose

  • Rancher

  • Ansible

  • OpenLdap

  • GitLab

  • GitHub

    • GitHub中开源项目维护流程手册
    • 分享我的开源项目Thank-Mirror
    • 2024年重磅开源项目 awesome-ops 已收录项目500个
    • 分享我的开源项目Cloud_Dns_Exporter,妈妈再也不担心我忘换证书了
    • 一个仅需三步配置就能生成免费个人博客的开源模板vdoing-template
    • 如何将个人的GitHub主页配置的优雅好看
    • 利用GitHub Actions自动为README添加TOC目录
    • 利用GitHub Actions自动将项目贡献者列表添加到README中
    • 利用GitHub Actions自动优雅地为项目构建Releases
    • 利用GitHub Actions自动获取博客rss文章
    • 利用GitHub Actions自动构建项目的docker镜像并发布到DockerHub
    • 利用GitHub Actions自动生成GitHub的Fans
    • 利用GitHub Actions自动生成个人star列表并归类
    • 利用GitHub Actions自动对仓库内图片进行无损压缩
    • 利用GitHub Actions自动检测项目中的问题链接
    • 利用GitHub Actions自动构建go项目的二进制到release
    • 利用github-slug-action暴漏Github Action上下文中的关键变量
    • 利用Github Action自动检测项目中 yaml 或 json 的语法
    • 记录最近在Github Action配置实践中的几个新的收获
      • 缓存的应用
        • Node 项目
        • Go 项目
        • docker 构建缓存
      • 一些组件
        • 添加 UPX
        • 添加 gox 命令
      • 制品共享
        • 制品上传
        • 制品下载
      • docker 镜像构建的思路
        • 思路一
        • 思路二
    • VMR一个开源的通用SDK版本管理器
  • Etcd

  • Consul

  • RabbitMQ

  • Kafka

  • Mysql

  • MongoDB

  • OpenVPN

  • Kvm

  • VMware

  • 配置文件详解

  • Other

  • 运维观止
  • GitHub
二丫讲梵
2025-04-12
目录

记录最近在Github Action配置实践中的几个新的收获

文章发布较早,内容可能过时,阅读注意甄别。

上周给 k8m (opens new window) 配置了 Github Actions 流水线,对自己而言,虽然以往配置过 go 项目的打 release 和 docker 镜像,但这次配置时又引入了一些新的思路方案,对自己的知识也是一个更新,这里做一下记录。

# 缓存的应用

以往的构建中,因为 GitHub 的构建环境没有网络的受限问题,于是并没有使用过缓存,这次是给别人项目贡献代码,所以格外注重构建时间上的体验,因此也研究学习了一下构建缓存的应用。

# Node 项目

完整示例:点我查看 (opens new window)

因为该项目使用的是 pnpm 构建工具,在 pnpm 官方文档 (opens new window)中对如何构建及使用缓存已经做了介绍,这里把当前实践的配置直接放在下边:

jobs:
  build-release:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [ 18 ]
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with:
          version: latest
      - name: 使用 Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "pnpm"
          cache-dependency-path: "ui/pnpm-lock.yaml"
      - name: 编译前端
        run: |
          cd ui
          pnpm install
          pnpm build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

其中参数也比较简单,不一一介绍,当流水线完成一次成功的构建之后,就可以在该流水线看到 node_modules 的缓存了:

My_Photor_1744453425010.webp

再次构建时,可以从构建日志中看到已经使用了该缓存:

My_Photor_1744453662598.webp

# Go 项目

完整示例:点我查看 (opens new window)

同理,go 语言项目在编译的时候,也可以配置 pkg 的缓存,以加快构建速度:

- name: 设置go环境
  uses: actions/setup-go@v5
  with:
    go-version-file: "go.mod"
    cache-dependency-path: "go.sum"
1
2
3
4
5

在定义 go 环境时,版本可以基于 mod 文件声明,缓存则可以通过 sum 声明。

同样,在有成功构建之后,下次再次构建,就可以看到缓存会启用了:

My_Photor_1744456534968.webp

# docker 构建缓存

完整示例:点我查看 (opens new window)

在构建 docker 镜像时,我们也可以应用一些缓存,从而加快构建速度。

一般在 GitHub Action 中,镜像构建使用的是 docker 官方提供的 action:build-push-action (opens new window),我之前也介绍过用法:利用GitHub Actions自动构建项目的docker镜像并发布到DockerHub (opens new window),之前的文章没有介绍缓存的用法,此处算做一个补充。

关于缓存的用法,官方也有文档:Cache management with GitHub Actions (opens new window)

docker 构建的缓存的存放方式,有多种,这里介绍两种,一种是基于镜像的缓存,一种是基于 GitHub Action 提供的缓存机制。

镜像缓存配置如下:

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v3

- name: Build and push
  uses: docker/build-push-action@v6
  with:
    push: true
    tags: user/app:latest
    cache-from: type=registry,ref=user/app:buildcache
    cache-to: type=registry,ref=user/app:buildcache,mode=max
1
2
3
4
5
6
7
8
9
10

构建之后,会在镜像仓库中生成一个标签为 buildcache 的镜像,后续构建则会先下载这个缓存,如有更新,也会自动再更新该缓存的内容。

Github 缓存配置如下:

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v3

- name: Build and push
  uses: docker/build-push-action@v6
  with:
    push: true
    tags: user/app:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max
1
2
3
4
5
6
7
8
9
10

两种方式都可以,按照个人喜好选择即可。

# 一些组件

# 添加 UPX

完整示例:点我查看 (opens new window)

upx 是一个通用的可以将二进制文件大小缩小约 50%-70%的工具,在开源项目中,在最佳实践中,尽可能优化二进制大小,也是一个应该考量的点,因此我所有的 Go 项目,都会默认使用该工具压缩。

通过在 Action 中添加如下内容,可以直接在构建环境中安装 upx 命令:

- name: 安装 UPX
  uses: crazy-max/ghaction-upx@v3
  with:
    install-only: true
1
2
3
4

进入到 action 的详情页面,可以看到更多介绍,不过这些参数就够用了,默认会安装最新版本。

# 添加 gox 命令

完整示例:点我查看 (opens new window)

gox 是一个可以并发交叉编译 Go 语言项目的工具,原项目目前归档不再更新,我这里使用的是 fork 中的一个还在维护的版本。

  uses: actions/setup-go@v5
  with:
    go-version-file: "go.mod"
    cache-dependency-path: "go.sum"
- run: go install github.com/authelia/gox@latest # setup gox
1
2
3
4
5

在设置好 go 环境之后,就可以直接安装 gox 了。安装好 gox 之后,就可以使用此工具并发编译了,这里也放一个个人目前使用的 Makefile (opens new window)。

# 制品共享

完整示例:点我查看 (opens new window)

在一些构建环境中,我们可能会把构建拆分成不同阶段。比如 k8m 是一个前后端在同一个仓库的项目,并且也设计成了前端 dist 制品 embed 到后端二进制架构。这个时候,前后端的构建会做一些分段设计,在不同阶段,就会出现制品共享的需求。

# 制品上传

- name: 上传到共享
  uses: actions/upload-artifact@v4
  with:
    name: workspace
    path: ui/dist
1
2
3
4
5

这是 GitHub 官方提供的 action,可以指定路径,把第一阶段的 dist 暂存。更多参数,可到 readme (opens new window) 详看。

# 制品下载

第一构建阶段上传的制品,可在第二阶段,用如下方式下载:

- name: 从共享下载
  uses: actions/download-artifact@v4
  with:
    name: workspace
    path: ui/dist
1
2
3
4
5

注意,需要 name 与上边上传的保持一致。同理,如果想要应用更多参数,可到 readme (opens new window) 查看。

# docker 镜像构建的思路

前提:这里提到的镜像构建,是指常规的构建出 linux/amd64,linux/arm64 两个平台的镜像。

# 思路一

之前,我都是用 build-push-action (opens new window) 提供的能力做的构建,比如以往的项目:go-ldap-admin (opens new window), 对应的 Dockerfile (opens new window),对应的流水线如下:

- name: Build and push
  uses: docker/build-push-action@v4
  with:
    context: .
    file: ./Dockerfile
    # 所需要的体系结构,可以在 Available platforms 步骤中获取所有的可用架构
    platforms: linux/arm64,linux/amd64
    # 镜像推送时间
    push: ${{ github.event_name != 'pull_request' }}
    # 给清单打上多个标签
    tags: |
      eryajf/go-ldap-admin:latest
      eryajf/go-ldap-admin:${{ steps.date.outputs.today }}
1
2
3
4
5
6
7
8
9
10
11
12
13

通过 action 中声明的不同 platform,然后用 go build -o go-ldap-admin 命令自动识别系统来构建对应系统的二进制。

这种构建思路,存在两个问题:

  1. 构建 arm 的镜像时,会格外慢,项目越大越明显。此问题我也提了 issue (opens new window)
  2. 因为 Dockerfile 设计成了分阶段构建,go 的 mod 缓存做起来也不是很方便,如果再加上前端的缓存,配置方案会更加复杂。

# 思路二

最近,我学习到一种新的知识点,可阅读跨平台 (opens new window)这篇文档。

简单来说,就是在构建多平台镜像时,我们会用到 --platform=linux/amd64 类似这样的参数。而在 Dockerfile 中,默认内置了三个变量,分别如下:

  • TARGETPLATFORM:解析值为 linux/amd64
  • TARGETOS:解析值为 linux
  • TARGETARCH :解析值为 amd64

这里做一个简单的 demo 进行验证,有 Dockerfile 如下:

FROM docker.cnb.cool/znb/images/alpine:3.21

ARG TARGETOS
ARG TARGETARCH
ARG TARGETPLATFORM

RUN echo "Target OS: ${TARGETOS}"
RUN echo "Target Arch: ${TARGETARCH}"
RUN echo "Target Platform: ${TARGETPLATFORM}"
1
2
3
4
5
6
7
8
9

然后分别运行不同平台的参数:

# amd
$ docker build -t eryajf --platform=linux/amd64  .

# arm
$ docker build -t eryajf --platform=linux/arm64  .
1
2
3
4
5

可以看到不同的结果:

My_Photor_1744463152452.webp

获取到这个知识点之后,我把整个构建的思路做了一下调整:

  • 原来的思路是在 dockerfile 中做分阶段构建,务求在里边独立完整地构建,不依赖其他操作。
  • 现在的思路是把二进制的构建放在 dockerfile 之外,dockerfile 只需把对应架构的二进制放到对应容器环境即可。

新的思路可以较好地规避以及解决掉思路一中提到的两个问题点:

  • 构建慢
    • 利用交叉编译,再加上 gox 的加持,构建速度提升非常大。
  • 缓存问题
    • 在外边构建,比在 Dockerfile 中配置缓存要容易得多。

因此,现在我个人针对 go 语言项目的镜像构建实践,可参考:eryajfctl (opens new window) 项目的 Makefile (opens new window) 和 Dockerfile (opens new window) 以及 Action (opens new window)。

这个项目本身就是一个模板项目,以后我也会把个人理解的 cobra 框架,以及 Github Action 构建 Go 项目的最佳实践,在该项目中体现,欢迎持续关注该项目。

微信 支付宝
#Github-Action
上次更新: 2025/04/15, 17:20:58
利用Github Action自动检测项目中 yaml 或 json 的语法
VMR一个开源的通用SDK版本管理器

← 利用Github Action自动检测项目中 yaml 或 json 的语法 VMR一个开源的通用SDK版本管理器→

最近更新
01
学习周刊-总第212期-2025年第21周
05-22
02
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
03
学习周刊-总第211期-2025年第20周
05-15
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式