使用GitHub工作流构建Docker镜像并推送至DockerHub

本文介绍如何创建执行 Docker 构建的工作流,然后将 Docker 映像发布到 Docker Hub

Docker容器是个好玩的东西,但是由于可能的网络限制玩起来并不是那么流畅

本着开放、共享、协作的互联网精神将代码开源并发布Docker镜像是一个很好的实践

本地也可以构建镜像并发布,但是使用自动的GitHub工作流执行这一操作可以给自己省时省事

以下正文内容以一个例子操作进行说明

准备工作

预先条件:注册Docker Hub,注册GitHub

在 Docker Hub 创建仓库

1、登录 Docker Hub ,点击 Create a Repository

Pasted image 20250511150014
Pasted image 20250511151238

在 Docker Hub 创建访问令牌

1、点击右上角账号 → Account Settings → Personal access token → New Access Token

Pasted image 20250511151708

2、填写参数生成令牌(权限选择 Read & Write),点击Generate

Pasted image 20250511152211
3、复制保存token(后续步骤要用)
Pasted image 20250511152710

创建GitHub 仓库(已有仓库可忽略)

1、创建新仓库(已有仓库可忽略)

Pasted image 20250511145102
2、本地仓库设置(已设置可忽略)

Pasted image 20250511145033

3、设置完成后查看仓库页面

Pasted image 20250511151144

在 GitHub 仓库配置 Secrets

1、进入 GitHub 仓库 → Settings → Secrets and variables → Actions

Pasted image 20250511153144
2、添加以下 Secrets:

  • DOCKERHUB_USERNAME:Docker Hub 用户名
  • DOCKERHUB_TOKEN:刚生成的 Docker Hub 访问token

Pasted image 20250511153354
Pasted image 20250511153557
Pasted image 20250511153639

创建 GitHub Actions 工作流文件

在项目根目录创建文件.github/workflows/docker-build-push.yml ,内容如下:

name: Publish Docker Image  # 工作流名称,显示在GitHub Actions界面

on:
  push:
    tags: [ 'v*.*.*' ]  # 触发条件:仅当推送符合vX.Y.Z格式的tag时运行(如v1.0.0)

jobs:
  push_to_registry:
    name: Push Docker Image  # 任务名称
    runs-on: ubuntu-latest   # 运行环境:最新版Ubuntu

    steps:
      # 步骤1:检出代码
      - name: Checkout Code
        uses: actions/checkout@v4  # 官方action,用于拉取仓库代码
        with:
          fetch-depth: 0  # 获取完整git历史记录(用于版本号提取)

      # 步骤2:设置Docker Buildx(多平台构建工具)
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3  # 配置Buildx环境

      # 步骤3:登录Docker Hub
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}  # 从GitHub Secrets读取用户名
          password: ${{ secrets.DOCKERHUB_TOKEN }}  # 从GitHub Secrets读取访问令牌

      # 步骤4:生成镜像标签
      - name: Extract Version Tags
        id: meta  # 步骤ID,用于后续引用输出
        uses: docker/metadata-action@v5  # 自动生成标签和元数据
        with:
          images: ${{ secrets.DOCKERHUB_USERNAME }}/docker-test  # 目标镜像名称(格式:用户名/仓库名)
          flavor: |
            latest=false  # 禁用metadata-action默认的latest标签生成逻辑
          tags: |  # 自定义标签规则(注意缩进)
            # 硬编码latest标签,仅当推送tag时生成
            type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}
            # 从git tag提取完整版本号(如v1.0.0 → 1.0.0)
            type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/') }}

      # 步骤5:构建并推送镜像
      - name: Build and Push
        uses: docker/build-push-action@v5
        with:
          context: .  # 构建上下文:当前目录
          push: true  # 启用推送(因为触发条件已限定为tag推送)
          tags: ${{ steps.meta.outputs.tags }}  # 使用前一步生成的标签
          labels: ${{ steps.meta.outputs.labels }}  # 自动生成的镜像标签
          platforms: linux/amd64  # 目标平台:Intel 64位
          # 构建缓存配置(从指定镜像拉取缓存)
          cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/docker-test:buildcache
          # 将构建缓存推送到指定镜像(模式设为max以包含全部缓存层)
          cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/docker-test:buildcache,mode=max

编写 Dockerfile

以下仅为测试,实际内容根据自己的项目编写

在项目根目录创建文件Dockerfile文件,内容如下:

FROM alpine:latest
COPY . /app
WORKDIR /app
CMD ["echo", "Hello Docker!"]

触发工作流

1、推送代码至GitHub仓库

git add .
git commit -m "Add Dockerfile and workflow"
git push origin main

注意:由于在工作流yaml文件中定义了触发条件:仅当推送符合vX.Y.Z格式的tag时运行,该git push步骤不会触发Github Action执行工作流

2、发布docker镜像(打Tag推送)

git tag -a v1.0.0 -m "Release 1.0.0"
git push origin v1.0.0

验证结果

GitHub Actions 日志

  • 在仓库的 Actions 选项卡查看构建状态
  • 确认Tag和Status

Docker Hub 检查

  • 登录 Docker Hub → Repositories → 找到镜像
  • 确认标签(如 latest 和 1.0.0)已存在

本地拉取测试

docker pull kiraster/docker-test:latest
docker pull kiraster/docker-test:1.0.0
docker run kiraster/docker-test:1.0.0


清除tag(扩展内容)

查看本地tag和远程tag

git tag -l                  # 查看本地标签
git ls-remote --tags origin # 查看远程标签

删除本地标签

删除单个标签

git tag -d v1.0.0  # 删除本地名为 v1.0.0 的标签

删除所有本地标签

git tag -l | xargs git tag -d  # 批量删除所有本地标签

删除远程仓库标签

删除单个远程标签

git push origin --delete v1.0.0  # 删除远程标签

删除所有远程标签

git ls-remote --tags origin | awk '{print $2}' | xargs git push origin --delete

最后

  • 确是省时省事
  • 后续部署run.claw.cloud玩一玩