GitHub Actions中拉取GHCR刚发布的Docker镜像部署方法
问题根因
报错由两个核心问题导致:
- Docker镜像仓库路径强制要求全小写格式,
${{ github.repository }}会保留仓库所有者、仓库名的原始大小写,直接拼接镜像地址会触发格式校验错误,仅手动修改仓库名大小写没有覆盖全场景。 - 你写的拉取命令没有指定镜像标签,Docker默认会拉取
latest标签,但当前配置使用的元数据组件不会给PR触发的构建自动打latest标签,只会生成pr-xx这类动态标签,即便路径转成小写也会因为找不到对应标签拉取失败。
修复方案
不需要调用额外接口查询标签或摘要,构建组件本身就会输出刚推送镜像的唯一标识,直接复用即可,步骤如下:
- 第一步:全局统一镜像名为小写格式,从根源解决大小写问题
在工作流全局env配置中增加小写转换处理:env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository | toLowerCase }} - 第二步:配置构建任务的输出参数,将构建产物的标识传递给下游部署任务
给build-and-push-image任务新增outputs字段,暴露构建生成的镜像摘要数据:
这里的jobs: build-and-push-image: runs-on: ubuntu-latest permissions: contents: read packages: write # 新增输出配置,供下游任务调用 outputs: image_digest: ${{ steps.build-and-push.outputs.digest }} steps: # 你原来的步骤逻辑保持不变,注意修正steps缩进,要和runs-on、permissions同属job的子层级,不要和job名同级 - name: Checkout repository uses: actions/checkout@v3 # 后续原有登录、元数据提取、构建推送步骤保持不变image_digest是构建推送组件原生输出的、刚推送到仓库的镜像唯一sha256值,完全动态,和本次构建一一对应,不会出现版本偏差。 - 第三步:调整部署任务逻辑,声明依赖关系,用镜像摘要拉取
部署任务必须等构建任务完成后再执行,拉取时直接用摘要而非动态标签,不需要关心pr编号的变化:deploy: # 声明依赖构建任务,才能读取到构建任务的输出参数 needs: build-and-push-image runs-on: ubuntu-latest steps: - name: Deploy to Digital Ocean droplet via SSH action uses: appleboy/ssh-action@v0.1.4 with: host: ${{ secrets.DO_HOST }} username: root key: ${{ secrets.DO_PRIVATE_SSHKEY }} port: 22 script: | # 先登录容器仓库,避免公开镜像拉取限流或权限问题 echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin # 用摘要拉取本次构建的镜像,完全不需要处理动态标签 docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build-and-push-image.outputs.image_digest }} # 后续启动容器时同样使用该摘要即可,例如: # docker run -d --name your-app ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build-and-push-image.outputs.image_digest }}
用镜像摘要拉取是生产环境推荐的做法:标签可能被覆盖、移动,但镜像摘要是全局唯一标识,和你本次构建推送的镜像完全对应,不会拉错版本,也不需要额外解析动态生成的pr类标签。
内容的提问来源于stack exchange,提问作者Oliver Angelil
相关产品推荐
相关产品推荐

