如何使用 GitHub Action 发布 Docker 镜像

前一阵子,我想在 Mathcheap 上实现 LaTeX 导出到 DOCX 格式的功能,一直没有找到合适的 JS 库去实现。目前可以很好实现这个功能的是 Pandoc , 美中不足的是 Pandoc 是 haskell 语言开发的,无法在 Node 环境和边缘服务器中运行。为了克服这个限制,我将 Pandoc 编译为 Webassembly。上周,我开源了 pandoc-wasm 这个编译流程,通过 Docker 镜像发布在 Docker Hub 上。在这个过程中,我探索了如何利用 GitHub Actions 自动构建和发布 Docker 镜像,极大地提升了开源项目的集成和部署效率。

为什么需要自动发布 Docker 镜像?

在尝试将 Pandoc 运行环境迁移到 Node 服务器的过程中,我试着构建了一套可靠的 pandoc-wasm 编译流程。因为 Mathcheap 依赖这套编译流程打包的产物,我打算开源并长期升级维护。Docker 是实现这一目标的绝佳工具,它可以将应用及其所有依赖打包到一个标准化的容器中。但每次手动构建镜像、打标签、然后推送到 Docker Hub 的过程,不仅繁琐,而且容易出错。尤其是在一个频繁迭代的开源项目中,自动化这一流程显得至关重要。这不仅能节省时间,还能确保每次代码合并后都能生成一个可靠的镜像。GitHub Actions 正是实现这一目标的利器。

准备工作

在开始之前,请确保你已经准备好以下几样东西:

  1. GitHub 仓库
  2. Docker Hub 账号
  3. Dockerfile 文件

Dockerfile 是一个文本文档,包含了一系列用户可以调用来组装镜像的指令。

第一步:配置 Docker Hub 访问凭证

为了让 GitHub Actions 能够登录你的 Docker Hub 账号并推送镜像,你需要将用户名和访问令牌(Access Token)安全地存储在 GitHub 中。

  1. 生成 Docker Hub 访问令牌

    • 登录 Docker Hub。
    • 进入 "Settings" -> "Personal access tokens"。
    • 点击 "Generate new token",创建一个具有读写删权限的令牌,并立即复制它
  2. 在 GitHub 仓库中设置 Secrets

    • 进入你的 GitHub 仓库,点击 "Settings" -> "Secrets and variables" -> "Actions"。
    • 点击 "New repository secret",创建两个新的 Secret:
      • DOCKERHUB_USERNAME: 你的 Docker Hub 用户名。
      • DOCKERHUB_TOKEN: 你刚刚生成的访问令牌。

通过这种方式,我们可以在工作流程中安全地使用这些凭证,而无需将它们硬编码到代码中。

第二步:创建 GitHub Actions 工作流程

接下来,在项目中创建一个 YAML 文件来定义自动化工作流程。

  1. 在仓库根目录下,创建 .github/workflows/ 文件夹。
  2. 在该文件夹下,创建一个新的 YAML 文件,例如 docker-publish.yml
yaml 复制代码
name: Build and Publish Docker image

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

env:
  IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: ./docker
          file: ./docker/Dockerfile
          push: true
          tags: |
            ${{ env.IMAGE_NAME }}:${{ github.ref_name }}
            ${{ env.IMAGE_NAME }}:latest

      - name: Update Docker Hub description
        uses: peter-evans/dockerhub-description@v4
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
          repository: ${{ env.IMAGE_NAME }}
          short-description: ${{ github.event.repository.description }}
          readme-filepath: ./docker/README.md

解读工作流程文件

分解一下这个 YAML 文件的关键部分:

  • 触发条件 on:
    • push.tags: 以 v 开头的标签(例如 v1.0.0)。这能把镜像版本与项目版本对齐。
    • workflow_dispatch: 支持从 GitHub UI 手动触发。
  • env.IMAGE_NAME: 最终镜像名是 shenlu89/pandoc-wasmshenlu89 是我在 Docker Hub 的用户名,DOCKERHUB_USERNAME,仓库名来自当前 GitHub 仓库的名字。
  • docker/build-push-action@v5:
    • context: 指向 ./docker 目录与其中的 Dockerfile。
    • push: true 表示构建完成后会推送到远程。
    • tags: 同时推版本标签和 latest
  • peter-evans/dockerhub-description@v4:
    • 用仓库的简介和 ./docker/README.md 自动更新 Docker Hub 页面描述。

提交代码触发 GitHub Actions

推送标签触发发布

  • 创建并推送一个符合规则的版本标签,例如 v1.0.0:
bash 复制代码
git add . && git commit -m 'feat: xxx' 
git tag v1.0.0
git push origin v1.0.0
  • 或者在 GitHub 的 Actions 页面手动点击"Run workflow"。

最后,触发 GitHub Actions 工作流,自动完成镜像构建和推送 Docker Hub。

相关推荐
whysqwhw1 小时前
Kotlin泛型位置规律与设计考量
github
Lisonseekpan2 小时前
为什么国内禁用docker呢?
运维·docker·容器
whysqwhw3 小时前
KuiklyUI的ViewRef设计
github
R-G-B4 小时前
【P1】win10安装 Docker教程
运维·docker·容器
snakecy5 小时前
常用命令记录
linux·运维·github
Java小学生丶5 小时前
非常简单的基于 Docker 自建 RustDesk 远程桌面教程
docker·远程桌面·异地组网
大刘讲IT6 小时前
赋能中小企业:基于五大开源模块的AI智能体构建方案与细化拆解
人工智能·经验分享·ai·开源·制造
来让爷抱一个6 小时前
企业级AI知识库新纪元:如何用开源力量重塑知识管理?
人工智能·开源
洛卡卡了6 小时前
Typora + PicGo + 阿里云 OSS:一套自己的图床方案
github·设计
逛逛GitHub6 小时前
本周 6 个最火火火火 GitHub 项目,AI 杀疯了。
github