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

⚠️ This is an article that was created 260 days ago, and the information may have evolved or changed.

本文介绍如何创建执行 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玩一玩