导读:本期聚焦于小伙伴创作的《如何用 GitHub Actions 自动构建并推送 Docker 镜像到镜像仓库?》,敬请观看详情。手动打包 Docker 镜像再推送到仓库,不仅重复劳动还容易遗漏版本号。借助 GitHub Actions,代码推送后就能自动完成镜像构建与分发。核心思路是在仓库内编写 workflow 文件,监听 push 或 tag 事件,调用官方 action 登录镜像服务,随后执行 docker build 与 docker push。相比本地脚本,这种方式环境一致、可追溯且支持多架构并行。文中会说明如何缓存依赖层来缩短耗时、用密钥保护账号凭证,并给出可直接复用的 YAML 配置与常见报错排查办法。

把源码变成可运行的容器镜像,原本需要在本地装好 Docker、手动执行构建命令再登录远程仓库推送。团队多人协作时,每个人机器环境不同,打出的镜像还可能不一致。GitHub Actions 作为托管在代码仓库里的持续集成服务,能让我们在每次提交后自动完成这套流程,既省事又可靠。

如何用 GitHub Actions 自动构建并推送 Docker 镜像到镜像仓库?

一、GitHub Actions 的工作机制

GitHub Actions 的核心概念是 workflow、job 和 step。workflow 是一个自动化流程,以 YAML 文件形式存放在仓库的 .github/workflows 目录中。当仓库发生指定事件,例如 push 到 main 分支或打上 v 开头标签,GitHub 会自动拉起一台临时的运行器(runner),按照文件里的描述一步步执行。

每个 workflow 可以包含多个 job,job 之间默认并行,也可以通过 needs 关键字形成依赖。在构建镜像的场景里,我们通常只需要一个 job,里面顺序执行:检出代码、登录镜像仓库、构建、推送。这种声明式写法让整个过程透明且可审查,任何人都能从仓库历史中看到某次镜像是怎么产生的。

1.1 事件触发方式

最常见的触发条件是 pushpull_request。如果只想在发布版本时构建镜像,可以限定为 tags 匹配特定正则。例如下面这段配置表示只在推送形如 v1.0.0 的标签时才运行:

on:
  push:
    tags:
      - 'v*'

另一种做法是结合 release 事件,当在 GitHub 页面上正式发布 Release 才触发,适合对生产镜像把关较严的团队。无论哪种,都建议在配置里写明分支或标签过滤,避免无关提交频繁消耗构建额度。

二、编写构建与推送的 workflow

下面给出一个可直接使用的完整示例,功能是在推送 tag 时构建镜像并推送到 Docker Hub。你需要先在仓库 Settings 的 Secrets 里配置 DOCKER_USERNAME 和 DOCKER_PASSWORD 两个密钥。

name: build-and-push

on:
  push:
    tags:
      - 'v*'

jobs:
  docker:
    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.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.ref_name }}

这个文件使用了三个官方 action。actions/checkout@v4 负责把仓库代码下载到运行器;docker/login-action@v3 完成镜像仓库认证;docker/build-push-action@v5 则封装了构建与推送。注意 github.ref_name 在 tag 触发时就是标签名,用它当镜像标签能直观对应版本。

如果你使用的是私有镜像仓库,只需把 login-action 的 registry 参数填上地址即可,例如 registry.ipipp.com。构建参数里也可以加入 platforms: linux/amd64,linux/arm64 来生成多架构镜像,方便在树莓派或云上不同机型部署。

2.1 使用缓存加速构建

每次从头构建会重复下载基础镜像和依赖,非常慢。build-push-action 支持通过 cache-fromcache-to 把层缓存到 GitHub Actions 缓存或镜像仓库。下面展示把缓存写入仓库自身缓存区的写法:

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.ref_name }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

开启后,第二次构建只会重新处理变动的层,速度通常能提升一半以上。需要注意免费账户的缓存空间有限,定期清理旧缓存可以避免额度浪费。

三、Dockerfile 的配合要点

workflow 只是调度者,真正决定镜像内容的还是 Dockerfile。为了让 GitHub Actions 构建顺利且产物小巧,推荐采用多阶段构建,把编译工具和运行环境分开。

FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o app main.go

FROM alpine:3.19
WORKDIR /app
COPY --from=builder /src/app .
CMD ["./app"]

上面的例子先用 Go 官方镜像编译出二进制,再拷贝到极简的 alpine 里。最终推送的镜像不包含编译器,体积可能从近 1GB 降到 10MB 出头。在 Actions 里构建这种 Dockerfile 和本地没有任何区别,但环境统一,不会因为某人本地装了旧版本 Go 而打出异常镜像。

另一个常见坑是忘记在 Dockerfile 里声明依赖安装步骤。由于运行器是干净环境,必须保证 COPY 之前用包管理器装齐所有系统库,否则构建会失败且报错信息不明显。建议在提交 workflow 前,先在本机用相同 Docker 版本跑一次 docker build 验证。

四、密钥与权限管理

镜像仓库账号密码绝对不能写进 YAML 明文。GitHub 的 Secrets 会在运行时以环境变量形式注入,日志中自动脱敏。除了账号密码,若推送到 GitHub 自身容器服务(GHCR),可以用内置的 GITHUB_TOKEN,并赋予 packages: write 权限。

permissions:
  contents: read
  packages: write

这样不需要额外配置密码,适合完全托管在 GitHub 生态内的项目。若是企业内部仓库,建议为 CI 单独建一个只读或只写账号,和开发者个人账号隔离,降低密钥泄露带来的影响范围。

五、常见问题排查

很多初次使用者会遇到登录失败,通常是因为 Secrets 名字拼错或密码含特殊字符未被正确解析。可以在 login 步骤前加一个只打印用户名的调试步骤(注意不要打印密码),确认变量传入正常。

另一个高频问题是构建超时,尤其是基础镜像来自境外仓库时。可以在 job 里加一个设置国内镜像加速的步骤,或者将常用基础镜像提前同步到私有仓库。此外,若项目含大量小文件,COPY . . 会较慢,可借助 .dockerignore 排除 node_modules、.git 等目录,显著减少上下文传输时间。

现象可能原因解决办法
denied: requested access to the resource is denied未登录或标签名不含用户名检查 login 步骤与 tags 格式
COPY failed: file not found路径被 dockerignore 忽略调整忽略规则或复制路径
cache export failed缓存空间不足清理旧缓存或关闭 cache-to

整体来看,GitHub Actions 构建 Docker 镜像是一套成本低、收益高的自动化方案。只要理清触发条件、密钥管理和 Dockerfile 优化三点,就能让每次发布都变得轻松可控。

GitHub_ActionsDockerCI_CD修改时间:2026-08-11 08:39:45

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。